core_service.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  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. for(i = 0; i < 256; i++)
  131. {
  132. uColor[i] = RGB888toRGB565(i, i, i, 1);
  133. }
  134. while(1)
  135. {
  136. Result = Task_GetEvent(prvService.LCDHandle, CORE_EVENT_ID_ANY, &Event, NULL, 0);
  137. switch(Event.ID)
  138. {
  139. case SERVICE_LCD_DRAW:
  140. Draw = (LCD_DrawStruct *)Event.Param1;
  141. if (Draw->Speed > 30000000)
  142. {
  143. SPI_SetTxOnlyFlag(Draw->SpiID, 1);
  144. }
  145. SPI_SetNewConfig(Draw->SpiID, Draw->Speed, Draw->Mode);
  146. SPI_DMATxInit(Draw->SpiID, LCD_SPI_TX_DMA_STREAM, 0);
  147. SPI_DMARxInit(Draw->SpiID, LCD_SPI_RX_DMA_STREAM, 0);
  148. prvCore_LCDCmd(Draw, 0x2a);
  149. BytesPutBe16(uPV.u8, Draw->x1 + Draw->xoffset);
  150. BytesPutBe16(uPV.u8 + 2, Draw->x2 + Draw->xoffset);
  151. prvCore_LCDData(Draw, uPV.u8, 4);
  152. prvCore_LCDCmd(Draw, 0x2b);
  153. BytesPutBe16(uPV.u8, Draw->y1 + Draw->yoffset);
  154. BytesPutBe16(uPV.u8 + 2, Draw->y2 + Draw->yoffset);
  155. prvCore_LCDData(Draw, uPV.u8, 4);
  156. prvCore_LCDCmd(Draw, 0x2c);
  157. GPIO_Output(Draw->CSPin, 0);
  158. // StartUS = GetSysTickUS();
  159. // SPI_Transfer(Draw->SpiID, Draw->Data, Draw->Data, Draw->Size, 2);
  160. SPI_BlockTransfer(Draw->SpiID, Draw->Data, Draw->Data, Draw->Size);
  161. // if (Draw->Size > 38000)
  162. // {
  163. // DBG("%u, %u", Draw->Size, (uint32_t)(GetSysTickUS() - StartUS));
  164. // }
  165. prvService.LCDDrawDoneByte += Draw->Size;
  166. free(Draw->Data);
  167. GPIO_Output(Draw->CSPin, 1);
  168. free(Draw);
  169. SPI_SetTxOnlyFlag(Draw->SpiID, 0);
  170. break;
  171. case SERVICE_CAMERA_DRAW:
  172. Draw = (LCD_DrawStruct *)Event.Param1;
  173. SPI_SetTxOnlyFlag(Draw->SpiID, 1);
  174. SPI_SetNewConfig(Draw->SpiID, Draw->Speed, Draw->Mode);
  175. SPI_DMATxInit(Draw->SpiID, LCD_SPI_TX_DMA_STREAM, 0);
  176. SPI_DMARxInit(Draw->SpiID, LCD_SPI_RX_DMA_STREAM, 0);
  177. prvCore_LCDCmd(Draw, 0x2a);
  178. BytesPutBe16(uPV.u8, Draw->x1 + Draw->xoffset);
  179. BytesPutBe16(uPV.u8 + 2, Draw->x2 + Draw->xoffset);
  180. prvCore_LCDData(Draw, uPV.u8, 4);
  181. prvCore_LCDCmd(Draw, 0x2b);
  182. BytesPutBe16(uPV.u8, Draw->y1 + Draw->yoffset);
  183. BytesPutBe16(uPV.u8 + 2, Draw->y2 + Draw->yoffset);
  184. prvCore_LCDData(Draw, uPV.u8, 4);
  185. prvCore_LCDCmd(Draw, 0x2c);
  186. GPIO_Output(Draw->CSPin, 0);
  187. switch(Draw->ColorMode)
  188. {
  189. case COLOR_MODE_RGB_565:
  190. SPI_BlockTransfer(Draw->SpiID, Draw->Data, Draw->Data, Draw->Size);
  191. break;
  192. case COLOR_MODE_GRAY:
  193. Size = Draw->Size/10;
  194. uPV.pu16 = malloc(Size * 2);
  195. for(i = 0; i < 10; i++)
  196. {
  197. for(j = 0; j < Size; j++)
  198. {
  199. uPV.pu16[j] = uColor[Draw->Data[i * Size + j]];
  200. }
  201. SPI_BlockTransfer(Draw->SpiID, uPV.pu8, uPV.pu8, Size * 2);
  202. }
  203. free(uPV.pu16);
  204. break;
  205. }
  206. free(Draw);
  207. GPIO_Output(Draw->CSPin, 1);
  208. SPI_SetTxOnlyFlag(Draw->SpiID, 0);
  209. break;
  210. }
  211. }
  212. }
  213. static void prvStorge_Task(void* params)
  214. {
  215. OS_EVENT Event;
  216. uint32_t *Param;
  217. SDHC_SPICtrlStruct *pSDHC;
  218. CommonFun_t CB;
  219. CBFuncEx_t CB2;
  220. HANDLE fd;
  221. while(1)
  222. {
  223. Task_GetEventByMS(prvService.StorgeHandle, CORE_EVENT_ID_ANY, &Event, NULL, 0);
  224. switch(Event.ID)
  225. {
  226. case SERVICE_SDHC_WRITE:
  227. pSDHC = (SDHC_SPICtrlStruct *)Event.Param1;
  228. if (pSDHC->WaitFree)
  229. {
  230. DBG("sdhc wait reboot");
  231. free(Event.Param2);
  232. free(Event.Param3);
  233. break;
  234. }
  235. Param = (uint32_t *)Event.Param3;
  236. SDHC_SpiWriteBlocks(pSDHC, Event.Param2, Param[0], Param[1]);
  237. free(Event.Param2);
  238. free(Event.Param3);
  239. break;
  240. case SERVICE_SPIFLASH_ERASE:
  241. if (prvService.pSpiFlash)
  242. {
  243. SPIFlash_Erase(prvService.pSpiFlash, Event.Param1, Event.Param2);
  244. }
  245. if (Event.Param3)
  246. {
  247. CB = (CommonFun_t )Event.Param3;
  248. CB();
  249. }
  250. break;
  251. case SERVICE_SPIFLASH_WRITE:
  252. if (prvService.pSpiFlash)
  253. {
  254. SPIFlash_Write(prvService.pSpiFlash, Event.Param1, Event.Param2, Event.Param3);
  255. prvService.FotaCRC32 = CRC32_Cal(prvService.CRC32_Table, Event.Param2, Event.Param3, prvService.FotaCRC32);
  256. prvService.FotaDoneLen += Event.Param3;
  257. }
  258. free(Event.Param2);
  259. break;
  260. case SERVICE_SPIFLASH_CLOSE:
  261. free(prvService.pSpiFlash);
  262. prvService.pSpiFlash = NULL;
  263. break;
  264. case SERVICE_FILE_WRITE:
  265. #ifdef __LUATOS__
  266. fd = luat_fs_fopen((char *)Event.Param1, "w");
  267. //DBG("%x,%s",fd, (char *)Event.Param1);
  268. if (fd)
  269. {
  270. luat_fs_fwrite(Event.Param2, Event.Param3, 1, fd);
  271. luat_fs_fclose(fd);
  272. }
  273. #endif
  274. prvService.FotaDoneLen += Event.Param3;
  275. free(Event.Param2);
  276. break;
  277. case SERVICE_RUN_USER_API:
  278. CB2 = (CBFuncEx_t)Event.Param1;
  279. CB2(Event.Param2, Event.Param3);
  280. break;
  281. }
  282. }
  283. }
  284. static void prvService_Task(void* params)
  285. {
  286. zbar_image_scanner_t *zbar_scanner;
  287. zbar_image_t *zbar_image;
  288. zbar_symbol_t *zbar_symbol;
  289. CBDataFun_t CBDataFun;
  290. PV_Union uPV;
  291. PV_Union uColor;
  292. HANDLE JPEGEncodeHandle = NULL;
  293. OS_EVENT Event;
  294. uint32_t i;
  295. CBFuncEx_t CB;
  296. Core_SetRGB565FixValue(0xff, 0xff, 0xff);
  297. // Audio_Test();
  298. while(1)
  299. {
  300. Task_GetEventByMS(prvService.ServiceHandle, CORE_EVENT_ID_ANY, &Event, NULL, 0);
  301. switch(Event.ID)
  302. {
  303. case SERVICE_SCAN_KEYBOARD:
  304. SoftKB_ScanOnce();
  305. break;
  306. case SERVICE_DECODE_QR:
  307. if (Event.Param3)
  308. {
  309. //此处代码可以更换成第三方解码
  310. CBDataFun = (CBDataFun_t)(Event.Param3);
  311. uPV.u32 = Event.Param2;
  312. zbar_scanner = zbar_image_scanner_create();
  313. zbar_image_scanner_set_config(zbar_scanner, 0, ZBAR_CFG_ENABLE, 1);
  314. zbar_image = zbar_image_create();
  315. zbar_image_set_format(zbar_image, *(int*)"Y800");
  316. zbar_image_set_size(zbar_image, uPV.u16[0], uPV.u16[1]);
  317. zbar_image_set_data(zbar_image, Event.Param1, uPV.u16[0] * uPV.u16[1], zbar_image_free_data);
  318. if (zbar_scan_image(zbar_scanner, zbar_image) > 0)
  319. {
  320. zbar_symbol = (zbar_symbol_t *)zbar_image_first_symbol(zbar_image);
  321. free(Event.Param1);
  322. //解码完成回调
  323. CBDataFun(zbar_symbol->data, zbar_symbol->datalen);
  324. }
  325. else
  326. {
  327. free(Event.Param1);
  328. //解码失败回调
  329. CBDataFun(NULL, 0);
  330. }
  331. zbar_image_destroy(zbar_image);
  332. zbar_image_scanner_destroy(zbar_scanner);
  333. }
  334. else
  335. {
  336. free(Event.Param1);
  337. }
  338. break;
  339. case SERVICE_ENCODE_JPEG_START:
  340. JPEGEncodeHandle = jpeg_encode_init(prvService.JPEGEncodeWriteFun, prvService.JPEGEncodeWriteParam, Event.Param2, Event.Param1 >> 16, Event.Param1 & 0x0000ffff, 3);
  341. break;
  342. case SERVICE_ENCODE_JPEG_RUN:
  343. if (JPEGEncodeHandle)
  344. {
  345. uColor.u32 = Event.Param1;
  346. switch(Event.Param3)
  347. {
  348. case COLOR_MODE_YCBCR_422_CBYCRY:
  349. uPV.pu8 = malloc((Event.Param2 >> 1) * 3);
  350. if (!uPV.pu8)
  351. {
  352. DBG("jpeg encode no momery");
  353. break;
  354. }
  355. Event.Param2 >>= 2;
  356. for(i = 0; i < Event.Param2; i++)
  357. {
  358. uPV.pu8[i * 6 + 0] = uColor.pu8[i * 4 + 1];
  359. uPV.pu8[i * 6 + 1] = uColor.pu8[i * 4 + 0];
  360. uPV.pu8[i * 6 + 2] = uColor.pu8[i * 4 + 2];
  361. uPV.pu8[i * 6 + 3] = uColor.pu8[i * 4 + 3];
  362. uPV.pu8[i * 6 + 4] = uColor.pu8[i * 4 + 0];
  363. uPV.pu8[i * 6 + 5] = uColor.pu8[i * 4 + 2];
  364. }
  365. jpeg_encode_run(JPEGEncodeHandle, uPV.pu8, 0);
  366. free(uPV.pu8);
  367. break;
  368. case COLOR_MODE_RGB_565:
  369. uPV.pu8 = malloc((Event.Param2 >> 1) * 3);
  370. if (!uPV.pu8)
  371. {
  372. DBG("jpeg encode no momery");
  373. break;
  374. }
  375. Event.Param2 >>= 1;
  376. for(i = 0; i < Event.Param2; i++)
  377. {
  378. RGB565toRGB888(uColor.pu16[i], uPV.pu8 + i * 3, 1);
  379. }
  380. jpeg_encode_run(JPEGEncodeHandle, uPV.pu8, 1);
  381. free(uPV.pu8);
  382. break;
  383. case COLOR_MODE_GRAY:
  384. uPV.pu8 = malloc(Event.Param2 * 3);
  385. if (!uPV.pu8)
  386. {
  387. DBG("jpeg encode no momery");
  388. break;
  389. }
  390. for(i = 0; i < Event.Param2; i++)
  391. {
  392. uPV.pu8[i * 3 + 0] = uColor.pu8[i];
  393. uPV.pu8[i * 3 + 1] = uColor.pu8[i];
  394. uPV.pu8[i * 3 + 2] = uColor.pu8[i];
  395. }
  396. jpeg_encode_run(JPEGEncodeHandle, uPV.pu8, 1);
  397. free(uPV.pu8);
  398. break;
  399. default:
  400. break;
  401. }
  402. }
  403. free(Event.Param1);
  404. break;
  405. case SERVICE_ENCODE_JPEG_END:
  406. if (JPEGEncodeHandle)
  407. {
  408. jpeg_encode_end(JPEGEncodeHandle);
  409. free(JPEGEncodeHandle);
  410. JPEGEncodeHandle = NULL;
  411. }
  412. if (Event.Param1)
  413. {
  414. CB = (CBFuncEx_t)Event.Param1;
  415. CB(NULL, Event.Param2);
  416. }
  417. break;
  418. case SERVICE_RUN_USER_API:
  419. CB = (CBFuncEx_t)Event.Param1;
  420. CB(Event.Param2, Event.Param3);
  421. break;
  422. }
  423. }
  424. }
  425. extern int luat_fs_init(void);
  426. static void prvLuatOS_Task(void* params)
  427. {
  428. // 文件系统初始化
  429. // luat_fs_init();
  430. // 载入LuatOS主入口
  431. luat_main();
  432. // 永不进入的代码, 避免编译警告.
  433. // for(;;)
  434. // {
  435. // vTaskDelayUntil( &xLastWakeTime, 2000 * portTICK_RATE_MS );
  436. // }
  437. }
  438. extern void luat_base_init(void);
  439. uint32_t Core_LCDDrawCacheLen(void)
  440. {
  441. if (prvService.LCDDrawRequireByte > prvService.LCDDrawDoneByte)
  442. {
  443. return (uint32_t)(prvService.LCDDrawRequireByte - prvService.LCDDrawDoneByte);
  444. }
  445. else
  446. {
  447. return 0;
  448. }
  449. }
  450. void Core_LCDDraw(LCD_DrawStruct *Draw)
  451. {
  452. prvService.LCDDrawRequireByte += Draw->Size;
  453. Task_SendEvent(prvService.LCDHandle, SERVICE_LCD_DRAW, Draw, 0, 0);
  454. }
  455. void Core_LCDDrawBlock(LCD_DrawStruct *Draw)
  456. {
  457. PV_Union uPV;
  458. uint64_t StartUS;
  459. // if (Draw->Speed > 30000000)
  460. // {
  461. // SPI_SetTxOnlyFlag(Draw->SpiID, 1);
  462. // }
  463. SPI_SetNewConfig(Draw->SpiID, Draw->Speed, Draw->Mode);
  464. // SPI_DMATxInit(Draw->SpiID, LCD_SPI_TX_DMA_STREAM, 0);
  465. // SPI_DMARxInit(Draw->SpiID, LCD_SPI_RX_DMA_STREAM, 0);
  466. prvCore_LCDCmd(Draw, 0x2a);
  467. BytesPutBe16(uPV.u8, Draw->x1 + Draw->xoffset);
  468. BytesPutBe16(uPV.u8 + 2, Draw->x2 + Draw->xoffset);
  469. prvCore_LCDData(Draw, uPV.u8, 4);
  470. prvCore_LCDCmd(Draw, 0x2b);
  471. BytesPutBe16(uPV.u8, Draw->y1 + Draw->yoffset);
  472. BytesPutBe16(uPV.u8 + 2, Draw->y2 + Draw->yoffset);
  473. prvCore_LCDData(Draw, uPV.u8, 4);
  474. prvCore_LCDCmd(Draw, 0x2c);
  475. GPIO_Output(Draw->CSPin, 0);
  476. // StartUS = GetSysTickUS();
  477. // SPI_Transfer(Draw->SpiID, Draw->Data, Draw->Data, Draw->Size, 2);
  478. SPI_BlockTransfer(Draw->SpiID, Draw->Data, Draw->Data, Draw->Size);
  479. // DBG("%u, %u", Draw->Size, (uint32_t)(GetSysTickUS() - StartUS));
  480. // if (Draw->Speed > 30000000)
  481. // {
  482. // Task_DelayUS(1);
  483. // }
  484. GPIO_Output(Draw->CSPin, 1);
  485. SPI_SetTxOnlyFlag(Draw->SpiID, 0);
  486. }
  487. void Core_CameraDraw(LCD_DrawStruct *Draw)
  488. {
  489. Task_SendEvent(prvService.LCDHandle, SERVICE_CAMERA_DRAW, Draw, 0, 0);
  490. }
  491. void Core_WriteSDHC(void *pSDHC, void *pData)
  492. {
  493. uint32_t *Param = malloc(8);
  494. Param[0] =((SDHC_SPICtrlStruct *)pSDHC)->CurBlock;
  495. Param[1] = ((SDHC_SPICtrlStruct *)pSDHC)->EndBlock - ((SDHC_SPICtrlStruct *)pSDHC)->CurBlock;
  496. Task_SendEvent(prvService.StorgeHandle, SERVICE_SDHC_WRITE, pSDHC, pData, Param);
  497. }
  498. void Core_DecodeQR(uint8_t *ImageData, uint16_t ImageW, uint16_t ImageH, CBDataFun_t CB)
  499. {
  500. PV_Union uPV;
  501. uPV.u16[0] = ImageW;
  502. uPV.u16[1] = ImageH;
  503. Task_SendEvent(prvService.ServiceHandle, SERVICE_DECODE_QR, ImageData, uPV.u32, CB);
  504. }
  505. void Core_ScanKeyBoard(void)
  506. {
  507. Task_SendEvent(prvService.ServiceHandle, SERVICE_SCAN_KEYBOARD, 0, 0, 0);
  508. }
  509. void Core_SetRGB565FixValue(uint8_t R, uint8_t G, uint8_t B)
  510. {
  511. prvService.RFix = R & 0x07;
  512. prvService.GFix = G & 0x03;
  513. prvService.BFix = B & 0x07;
  514. }
  515. void Core_EncodeJPEGSetup(HANDLE Fun, void *pParam)
  516. {
  517. if (Fun)
  518. {
  519. prvService.JPEGEncodeWriteFun = Fun;
  520. }
  521. else
  522. {
  523. prvService.JPEGEncodeWriteFun = prv_CoreJpegSave;
  524. }
  525. prvService.JPEGEncodeWriteParam = pParam;
  526. }
  527. void Core_EncodeJPEGStart(uint32_t Width, uint32_t Height, uint8_t Quality)
  528. {
  529. Task_SendEvent(prvService.ServiceHandle, SERVICE_ENCODE_JPEG_START, (Width << 16 | Height), Quality, 0);
  530. }
  531. void Core_EncodeJPEGRun(uint8_t *Data, uint32_t Len, uint8_t ColorMode)
  532. {
  533. Task_SendEvent(prvService.ServiceHandle, SERVICE_ENCODE_JPEG_RUN, Data, Len, ColorMode);
  534. }
  535. void Core_EncodeJPEGEnd(CBFuncEx_t CB, void *pParam)
  536. {
  537. Task_SendEvent(prvService.ServiceHandle, SERVICE_ENCODE_JPEG_END, CB, pParam, 0);
  538. }
  539. void Core_PrintMemInfo(void)
  540. {
  541. uint32_t curalloc, totfree, maxfree;
  542. OS_MemInfo(&curalloc, &totfree, &maxfree);
  543. DBG("curalloc %uB, totfree %uB, maxfree %uB", curalloc, totfree, maxfree);
  544. }
  545. static uint8_t disassembly_ins_is_bl_blx(uint32_t addr) {
  546. uint16_t ins1 = *((uint16_t *)addr);
  547. uint16_t ins2 = *((uint16_t *)(addr + 2));
  548. #define BL_INS_MASK 0xF800
  549. #define BL_INS_HIGH 0xF800
  550. #define BL_INS_LOW 0xF000
  551. #define BLX_INX_MASK 0xFF00
  552. #define BLX_INX 0x4700
  553. if ((ins2 & BL_INS_MASK) == BL_INS_HIGH && (ins1 & BL_INS_MASK) == BL_INS_LOW) {
  554. return 1;
  555. } else if ((ins2 & BLX_INX_MASK) == BLX_INX) {
  556. return 1;
  557. } else {
  558. return 0;
  559. }
  560. }
  561. static void prvCore_PrintTaskStack(HANDLE TaskHandle)
  562. {
  563. uint32_t SP, StackAddress, Len, i, PC;
  564. uint32_t Buffer[16];
  565. if (!TaskHandle) return;
  566. char *Name = vTaskInfo(TaskHandle, &SP, &StackAddress, &Len);
  567. Len *= 4;
  568. DBG_Trace("%s call stack info:", Name);
  569. for(i = 0; i < 16, SP < StackAddress + Len; SP += 4)
  570. {
  571. PC = *((uint32_t *) SP) - 4;
  572. if ((PC > __FLASH_APP_START_ADDR__) && (PC < (__FLASH_BASE_ADDR__ + __CORE_FLASH_BLOCK_NUM__ * __FLASH_BLOCK_SIZE__)))
  573. {
  574. if (PC % 2 == 0) {
  575. continue;
  576. }
  577. PC = *((uint32_t *) SP) - 1;
  578. if (disassembly_ins_is_bl_blx(PC - 4))
  579. {
  580. DBG_Trace("%x", PC);
  581. i++;
  582. }
  583. }
  584. }
  585. }
  586. void Core_PrintServiceStack(void)
  587. {
  588. prvCore_PrintTaskStack(prvService.LCDHandle);
  589. prvCore_PrintTaskStack(prvService.UserHandle);
  590. prvCore_PrintTaskStack(prvService.ServiceHandle);
  591. }
  592. void Core_DebugMem(uint8_t HeapID, const char *FuncName, uint32_t Line)
  593. {
  594. int32_t curalloc, totfree, maxfree;
  595. OS_MemInfo(&curalloc, &totfree, &maxfree);
  596. if (!prvService.InitAllocMem)
  597. {
  598. prvService.InitAllocMem = curalloc;
  599. prvService.LastAllocMem = curalloc;
  600. DBG_Printf("base %d\r\n", prvService.InitAllocMem);
  601. }
  602. else
  603. {
  604. DBG_Printf("%s %u:total %d last %d\r\n", FuncName, Line, curalloc - prvService.InitAllocMem, curalloc - prvService.LastAllocMem);
  605. prvService.LastAllocMem = curalloc;
  606. }
  607. }
  608. static void Core_OTAReady(void)
  609. {
  610. prvService.FotaReady = 1;
  611. }
  612. int Core_OTAInit(CoreUpgrade_HeadStruct *Head, uint32_t size)
  613. {
  614. prvService.FotaReady = 0;
  615. PV_Union uPV;
  616. Flash_Erase(__FLASH_OTA_INFO_ADDR__, __FLASH_SECTOR_SIZE__);
  617. if (prvService.pFotaHead)
  618. {
  619. free(prvService.pFotaHead);
  620. }
  621. prvService.pFotaHead = Head;
  622. OS_ReInitBuffer(&prvService.FotaDataBuf, __FLASH_BLOCK_SIZE__);
  623. prvService.FotaPos = 0;
  624. uPV.u32 = prvService.pFotaHead->Param1;
  625. if (uPV.u8[1] == CORE_OTA_OUT_SPI_FLASH)
  626. {
  627. if (prvService.pSpiFlash)
  628. {
  629. free(prvService.pSpiFlash);
  630. }
  631. }
  632. prvService.FotaCRC32 = 0xffffffff;
  633. prvService.FotaPos = 0;
  634. prvService.FotaDoneLen = 0;
  635. prvService.FotaFindHead = 0;
  636. if (uPV.u8[1] == CORE_OTA_OUT_SPI_FLASH)
  637. {
  638. prvService.pSpiFlash = zalloc(sizeof(SPIFlash_CtrlStruct));
  639. prvService.pSpiFlash->SpiID = uPV.u8[2];
  640. uPV.u32 = prvService.pFotaHead->Param2;
  641. prvService.pSpiFlash->CSPin = uPV.u8[3];
  642. prvService.pSpiFlash->IsBlockMode = 1;
  643. SPIFlash_Init(prvService.pSpiFlash, NULL);
  644. if (!prvService.pSpiFlash->IsInit)
  645. {
  646. return -1;
  647. }
  648. Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_ERASE, prvService.pFotaHead->DataStartAddress, size, Core_OTAReady);
  649. }
  650. else
  651. {
  652. prvService.FotaReady = 1;
  653. }
  654. return 0;
  655. }
  656. int Core_OTAWrite(uint8_t *Data, uint32_t Len)
  657. {
  658. if (!prvService.FotaFindHead)
  659. {
  660. if (Len < sizeof(CoreUpgrade_FileHeadStruct))
  661. {
  662. return -1;
  663. }
  664. CoreUpgrade_FileHeadStruct Head;
  665. memcpy(&Head, Data, sizeof(CoreUpgrade_FileHeadStruct));
  666. if (Head.MaigcNum != __APP_START_MAGIC__)
  667. {
  668. DBG("%x", Head.MaigcNum);
  669. return -1;
  670. }
  671. uint32_t crc32 = CRC32_Cal(prvService.CRC32_Table, &Head.MainVersion, sizeof(CoreUpgrade_FileHeadStruct) - 8, 0xffffffff);
  672. if (crc32 != Head.CRC32)
  673. {
  674. DBG("crc32 %x,%x", crc32, Head.CRC32);
  675. return -1;
  676. }
  677. //由于是整包升级,就不考虑版本的事情了
  678. prvService.FotaFindHead = 1;
  679. prvService.pFotaHead->DataLen = Head.DataLen;
  680. prvService.pFotaHead->DataCRC32 = Head.DataCRC32;
  681. prvService.pFotaHead->CRC32 = CRC32_Cal(prvService.CRC32_Table, &prvService.pFotaHead->Param1, sizeof(CoreUpgrade_HeadStruct) - 8, 0xffffffff);
  682. Data = Data + sizeof(CoreUpgrade_FileHeadStruct);
  683. Len -= sizeof(CoreUpgrade_FileHeadStruct);
  684. if (!Len) return 0;
  685. }
  686. uint32_t DummyLen;
  687. PV_Union uPV;
  688. uPV.u32 = prvService.pFotaHead->Param1;
  689. if (!prvService.pFotaHead )
  690. {
  691. return -1;
  692. }
  693. switch(uPV.u8[1])
  694. {
  695. case CORE_OTA_IN_FLASH:
  696. break;
  697. case CORE_OTA_OUT_SPI_FLASH:
  698. if (!prvService.pSpiFlash)
  699. {
  700. return -1;
  701. }
  702. break;
  703. case CORE_OTA_IN_FILE:
  704. break;
  705. }
  706. DummyLen = ((prvService.FotaDataBuf.MaxLen - prvService.FotaDataBuf.Pos) >= Len)?Len:(prvService.FotaDataBuf.MaxLen - prvService.FotaDataBuf.Pos);
  707. OS_BufferWrite(&prvService.FotaDataBuf, Data, DummyLen);
  708. if (prvService.FotaDataBuf.Pos == __FLASH_BLOCK_SIZE__)
  709. {
  710. switch(uPV.u8[1])
  711. {
  712. case CORE_OTA_IN_FLASH:
  713. prvService.FotaDataBuf.Pos = 0;
  714. prvService.FotaDoneLen += __FLASH_BLOCK_SIZE__;
  715. break;
  716. case CORE_OTA_OUT_SPI_FLASH:
  717. Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_WRITE, prvService.pFotaHead->DataStartAddress + prvService.FotaPos, prvService.FotaDataBuf.Data, __FLASH_BLOCK_SIZE__);
  718. OS_InitBuffer(&prvService.FotaDataBuf, __FLASH_BLOCK_SIZE__);
  719. break;
  720. case CORE_OTA_IN_FILE:
  721. Task_SendEvent(prvService.StorgeHandle, SERVICE_FILE_WRITE, prvService.pFotaHead->FilePath, prvService.FotaDataBuf.Data, prvService.FotaDataBuf.Pos);
  722. OS_InitBuffer(&prvService.FotaDataBuf, __FLASH_BLOCK_SIZE__);
  723. break;
  724. }
  725. prvService.FotaPos += __FLASH_BLOCK_SIZE__;
  726. }
  727. else if ((prvService.FotaPos + prvService.FotaDataBuf.Pos) >= prvService.pFotaHead->DataLen)
  728. {
  729. // DBG("all data rx");
  730. switch(uPV.u8[1])
  731. {
  732. case CORE_OTA_IN_FLASH:
  733. prvService.FotaDoneLen += prvService.FotaDataBuf.Pos;
  734. OS_DeInitBuffer(&prvService.FotaDataBuf);
  735. break;
  736. case CORE_OTA_OUT_SPI_FLASH:
  737. Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_WRITE, prvService.pFotaHead->DataStartAddress + prvService.FotaPos, prvService.FotaDataBuf.Data, prvService.FotaDataBuf.Pos);
  738. memset(&prvService.FotaDataBuf, 0, sizeof(prvService.FotaDataBuf));
  739. break;
  740. case CORE_OTA_IN_FILE:
  741. Task_SendEvent(prvService.StorgeHandle, SERVICE_FILE_WRITE, prvService.pFotaHead->FilePath, prvService.FotaDataBuf.Data, prvService.FotaDataBuf.Pos);
  742. memset(&prvService.FotaDataBuf, 0, sizeof(prvService.FotaDataBuf));
  743. break;
  744. }
  745. return 0;
  746. }
  747. if (DummyLen < Len)
  748. {
  749. OS_BufferWrite(&prvService.FotaDataBuf, Data + DummyLen, Len - DummyLen);
  750. }
  751. if (prvService.FotaDoneLen < prvService.FotaPos)
  752. {
  753. return (prvService.FotaPos - prvService.FotaDoneLen);
  754. }
  755. return 1;
  756. }
  757. uint8_t Core_OTACheckReadyStart(void)
  758. {
  759. return prvService.FotaReady;
  760. }
  761. int Core_OTACheckDone(void)
  762. {
  763. if (!prvService.pFotaHead )
  764. {
  765. return -1;
  766. }
  767. if (prvService.FotaDoneLen >= prvService.pFotaHead->DataLen)
  768. {
  769. return (prvService.FotaCRC32 == prvService.pFotaHead->DataCRC32)?0:-1;
  770. }
  771. return 1;
  772. }
  773. //static void Core_OTACheckSpiFlash(void)
  774. //{
  775. // CoreUpgrade_SectorStruct Sector;
  776. // Buffer_Struct ReadBuffer;
  777. // Buffer_Struct DataBuffer;
  778. // int result;
  779. // uint32_t Check;
  780. // uint32_t DoneLen, ReadLen;
  781. // volatile uint32_t ProgramPos, FlashPos;
  782. // uint32_t LzmaDataLen;
  783. // uint8_t LzmaHead[LZMA_PROPS_SIZE + 8];
  784. // uint8_t LzmaHeadLen;
  785. //
  786. // DoneLen = 0;
  787. // OS_InitBuffer(&DataBuffer, SPI_FLASH_BLOCK_SIZE);
  788. // OS_InitBuffer(&ReadBuffer, SPI_FLASH_BLOCK_SIZE);
  789. // while(DoneLen < prvService.pFotaHead->DataLen)
  790. // {
  791. // ReadBuffer.Pos = sizeof(CoreUpgrade_SectorStruct);
  792. // SPIFlash_Read(prvService.pSpiFlash, prvService.pFotaHead->DataStartAddress + DoneLen, ReadBuffer.Data, ReadBuffer.Pos, 1);
  793. // DoneLen += sizeof(CoreUpgrade_SectorStruct);
  794. // memcpy(&Sector, ReadBuffer.Data, sizeof(CoreUpgrade_SectorStruct));
  795. // DBG("%x,%x,%x,%x,%x", Sector.MaigcNum, Sector.StartAddress, Sector.TotalLen, Sector.DataLen, Sector.DataCRC32);
  796. // if (Sector.MaigcNum != __APP_START_MAGIC__)
  797. // {
  798. // DBG("ota sector info error %x", Sector.MaigcNum);
  799. // return;
  800. // }
  801. // ProgramPos = Sector.StartAddress;
  802. // FlashPos = DoneLen + prvService.pFotaHead->DataStartAddress;
  803. // DoneLen += Sector.TotalLen;
  804. //
  805. // Check = 0xffffffff;
  806. // ReadLen = 0;
  807. // while(ReadLen < Sector.TotalLen)
  808. // {
  809. // DBG("ota %x,%x,%u,%u", ProgramPos, FlashPos, ReadLen, Sector.TotalLen);
  810. // ReadBuffer.Pos = 1;
  811. // SPIFlash_Read(prvService.pSpiFlash, FlashPos, ReadBuffer.Data, ReadBuffer.Pos, 1);
  812. // FlashPos += ReadBuffer.Pos;
  813. // ReadLen += ReadBuffer.Pos;
  814. // LzmaHeadLen = ReadBuffer.Data[0];
  815. // if (LzmaHeadLen > sizeof(LzmaHead))
  816. // {
  817. // DBG("ota zip head error");
  818. // return;
  819. // }
  820. // ReadBuffer.Pos = LzmaHeadLen + 4;
  821. // SPIFlash_Read(prvService.pSpiFlash, FlashPos, ReadBuffer.Data, ReadBuffer.Pos, 1);
  822. // FlashPos += ReadBuffer.Pos;
  823. // ReadLen += ReadBuffer.Pos;
  824. // memcpy(LzmaHead, ReadBuffer.Data, LzmaHeadLen);
  825. // memcpy(&LzmaDataLen, ReadBuffer.Data + LzmaHeadLen, 4);
  826. // ReadBuffer.Pos = LzmaDataLen;
  827. // SPIFlash_Read(prvService.pSpiFlash, FlashPos, ReadBuffer.Data, ReadBuffer.Pos, 1);
  828. // FlashPos += ReadBuffer.Pos;
  829. // ReadLen += ReadBuffer.Pos;
  830. //
  831. // DataBuffer.Pos = __FLASH_BLOCK_SIZE__;
  832. // result = LzmaUncompress(DataBuffer.Data, &DataBuffer.Pos, ReadBuffer.Data, &LzmaDataLen, LzmaHead, LzmaHeadLen);
  833. // if (DataBuffer.Pos != __FLASH_BLOCK_SIZE__)
  834. // {
  835. // DataBuffer.Pos = Sector.DataLen - (ProgramPos - Sector.StartAddress);
  836. // }
  837. // Check = CRC32_Cal(prvService.CRC32_Table, DataBuffer.Data, DataBuffer.Pos, Check);
  838. // ProgramPos += DataBuffer.Pos;
  839. //
  840. // }
  841. // DBG("%u, %u", ProgramPos - Sector.StartAddress, Sector.DataLen);
  842. // if (Sector.DataCRC32 != Check)
  843. // {
  844. //// Reboot = 1;
  845. // DBG("ota %x check crc32 fail %x %x", Sector.StartAddress, Check, Sector.DataCRC32);
  846. // return;
  847. // }
  848. // else
  849. // {
  850. // DBG("ota %x check ok", Sector.StartAddress);
  851. // }
  852. // }
  853. // OS_DeInitBuffer(&DataBuffer);
  854. // OS_DeInitBuffer(&ReadBuffer);
  855. //}
  856. void Core_OTAEnd(uint8_t isOK)
  857. {
  858. PV_Union uPV;
  859. uPV.u32 = prvService.pFotaHead->Param1;
  860. if (isOK && prvService.pFotaHead)
  861. {
  862. Flash_Erase(__FLASH_OTA_INFO_ADDR__, __FLASH_SECTOR_SIZE__);
  863. Flash_Program(__FLASH_OTA_INFO_ADDR__, prvService.pFotaHead, sizeof(CoreUpgrade_HeadStruct));
  864. switch(uPV.u8[1])
  865. {
  866. case CORE_OTA_IN_FLASH:
  867. break;
  868. case CORE_OTA_OUT_SPI_FLASH:
  869. // Core_OTACheckSpiFlash();
  870. free(prvService.pSpiFlash);
  871. prvService.pSpiFlash = NULL;
  872. break;
  873. case CORE_OTA_IN_FILE:
  874. break;
  875. }
  876. }
  877. else
  878. {
  879. switch(uPV.u8[1])
  880. {
  881. case CORE_OTA_IN_FLASH:
  882. break;
  883. case CORE_OTA_OUT_SPI_FLASH:
  884. Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_CLOSE, 0, 0, 0);
  885. break;
  886. case CORE_OTA_IN_FILE:
  887. break;
  888. }
  889. }
  890. free(prvService.pFotaHead);
  891. prvService.pFotaHead = NULL;
  892. OS_DeInitBuffer(&prvService.FotaDataBuf);
  893. }
  894. void Core_ServiceRunUserAPIWithFile(CBFuncEx_t CB, void *pData, void *pParam)
  895. {
  896. Task_SendEvent(prvService.StorgeHandle, SERVICE_RUN_USER_API, CB, pData, pParam);
  897. }
  898. void Core_LCDTaskInit(void)
  899. {
  900. prvService.LCDHandle = Task_Create(prvLCD_Task, NULL, 2 * 1024, HW_TASK_PRO, "lcd task");
  901. }
  902. void Core_ServiceInit(void)
  903. {
  904. CRC32_CreateTable(prvService.CRC32_Table, CRC32_GEN);
  905. prvService.ServiceHandle = Task_Create(prvService_Task, NULL, 4 * 1024, SERVICE_TASK_PRO, "service task");
  906. }
  907. void Core_UserTaskInit(void)
  908. {
  909. #ifdef __LUATOS__
  910. prvService.UserHandle = Task_Create(prvLuatOS_Task, NULL, 8*1024, LUATOS_TASK_PRO, "luatos task");
  911. luat_base_init();
  912. #endif
  913. }
  914. void Core_StorgeTaskInit(void)
  915. {
  916. prvService.StorgeHandle = Task_Create(prvStorge_Task, NULL, 1024, SERVICE_TASK_PRO, "storge task");
  917. }
  918. INIT_TASK_EXPORT(Core_LCDTaskInit, "0");
  919. INIT_TASK_EXPORT(Core_ServiceInit, "1");
  920. INIT_TASK_EXPORT(Core_StorgeTaskInit, "2");
  921. INIT_TASK_EXPORT(Core_UserTaskInit, "5");
  922. #endif