luat_camera_air105.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  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 "zlib.h"
  22. #include "app_interface.h"
  23. #include "luat_base.h"
  24. #include "luat_lcd.h"
  25. #include "luat_camera.h"
  26. #include "luat_msgbus.h"
  27. #include "luat_spi.h"
  28. #include "luat_gpio.h"
  29. #include "app_interface.h"
  30. #include "zbar.h"
  31. #include "symbol.h"
  32. #include "image.h"
  33. #define LUAT_LOG_TAG "camera"
  34. #include "luat_log.h"
  35. typedef struct
  36. {
  37. uint64_t StartTick;
  38. Buffer_Struct FileBuffer;
  39. Buffer_Struct RawBuffer;
  40. Buffer_Struct JPEGSavePath;
  41. Timer_t *CheckTimer;
  42. uint8_t *DataCache;
  43. uint8_t *VideoCache;
  44. uint32_t TotalSize;
  45. uint32_t CurSize;
  46. uint32_t VLen;
  47. uint32_t drawVLen;
  48. uint16_t Width;
  49. uint16_t Height;
  50. uint8_t DataBytes;
  51. uint8_t IsDecoding;
  52. uint8_t JPEGQuality;
  53. uint8_t CaptureMode;
  54. uint8_t CaptureWait;
  55. uint8_t JPEGEncodeDone;
  56. uint8_t PWMID;
  57. uint8_t I2CID;
  58. uint8_t NewDataFlag;
  59. uint8_t DrawLCD;
  60. }Camera_CtrlStruct;
  61. static Camera_CtrlStruct prvCamera;
  62. static struct luat_camera_conf camera_conf;
  63. static luat_lcd_conf_t* lcd_conf;
  64. static int32_t prvCamera_DataTimeout(void *pData, void *pParam)
  65. {
  66. if (!prvCamera.NewDataFlag)
  67. {
  68. rtos_msg_t msg = {0};
  69. {
  70. msg.handler = l_camera_handler;
  71. msg.ptr = NULL;
  72. msg.arg1 = 0;
  73. msg.arg2 = 0;
  74. luat_msgbus_put(&msg, 1);
  75. }
  76. }
  77. prvCamera.NewDataFlag = 0;
  78. }
  79. static void Camera_SaveJPEGData(void *Cxt, void *pData, int Size)
  80. {
  81. OS_BufferWrite(Cxt, pData, Size);
  82. }
  83. static int32_t Camera_SaveJPEGDone(void *pData, void *pParam)
  84. {
  85. HANDLE fd;
  86. if (prvCamera.JPEGSavePath.Data)
  87. {
  88. fd = luat_fs_fopen(prvCamera.JPEGSavePath.Data, "w");
  89. }
  90. else
  91. {
  92. fd = luat_fs_fopen("/capture.jpg", "w");
  93. }
  94. if (fd)
  95. {
  96. LLOGD("capture data %ubyte", luat_fs_fwrite(prvCamera.FileBuffer.Data, prvCamera.FileBuffer.Pos, 1, fd));
  97. luat_fs_fclose(fd);
  98. }
  99. OS_DeInitBuffer(&prvCamera.FileBuffer);
  100. prvCamera.CaptureWait = 1;
  101. prvCamera.JPEGEncodeDone = 1;
  102. prvCamera.CaptureMode = 0;
  103. Core_EncodeJPEGSetup(NULL, &prvCamera);
  104. rtos_msg_t msg = {0};
  105. {
  106. msg.handler = l_camera_handler;
  107. msg.ptr = NULL;
  108. msg.arg1 = 0;
  109. msg.arg2 = 1;
  110. luat_msgbus_put(&msg, 1);
  111. }
  112. }
  113. void DecodeQR_CBDataFun(uint8_t *Data, uint32_t Len){
  114. prvCamera.IsDecoding = 0;
  115. rtos_msg_t msg = {0};
  116. if (Data){
  117. msg.handler = l_camera_handler;
  118. msg.ptr = Data;
  119. msg.arg1 = 0;
  120. msg.arg2 = Len;
  121. luat_msgbus_put(&msg, 1);
  122. }
  123. }
  124. static int32_t Camera_DrawLcd(void *DrawData, uint8_t Scan){
  125. LCD_DrawStruct *draw = malloc(sizeof(LCD_DrawStruct));
  126. if (!draw){
  127. DBG("lcd flush no memory");
  128. return -1;
  129. }
  130. uint8_t CPHA = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.CPHA;
  131. uint8_t CPOL = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.CPOL;
  132. draw->DCDelay = lcd_conf->dc_delay_us;
  133. draw->Mode = SPI_MODE_0;
  134. if(CPHA&&CPOL)draw->Mode = SPI_MODE_3;
  135. else if(CPOL)draw->Mode = SPI_MODE_2;
  136. else if(CPHA)draw->Mode = SPI_MODE_1;
  137. draw->Speed = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.bandrate;
  138. if (((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->bus_id == 5) draw->SpiID = HSPI_ID0;
  139. else draw->SpiID = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->bus_id;
  140. draw->CSPin = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.cs;
  141. draw->DCPin = lcd_conf->pin_dc;
  142. draw->xoffset = lcd_conf->xoffset;
  143. draw->yoffset = lcd_conf->yoffset;
  144. if (Scan == 0){
  145. draw->x1 = 0;
  146. draw->x2 = lcd_conf->w -1;
  147. draw->y1 = prvCamera.VLen;
  148. draw->y2 = prvCamera.VLen + prvCamera.drawVLen -1;
  149. draw->Size = (draw->x2 - draw->x1 + 1) * (draw->y2 - draw->y1 + 1) * 2;
  150. draw->ColorMode = COLOR_MODE_RGB_565;
  151. draw->Data = malloc(draw->Size);
  152. if (!draw->Data){
  153. DBG("lcd flush data no memory");
  154. free(draw);
  155. return -1;
  156. }
  157. memcpy(draw->Data, DrawData, draw->Size);
  158. Core_LCDDraw(draw);
  159. }else if(Scan == 1){
  160. draw->x1 = 0;
  161. draw->x2 = prvCamera.Width - 1;
  162. draw->y1 = 0;
  163. draw->y2 = prvCamera.Height - 1;
  164. draw->Size = prvCamera.TotalSize;
  165. draw->ColorMode = COLOR_MODE_GRAY;
  166. draw->Data = DrawData;
  167. Core_CameraDraw(draw);
  168. }else{
  169. DBG("Scan error");
  170. free(draw);
  171. return -1;
  172. }
  173. }
  174. static int32_t prvCamera_DCMICB(void *pData, void *pParam){
  175. uint8_t zbar_scan = (uint8_t)pParam;
  176. Buffer_Struct *RxBuf = (Buffer_Struct *)pData;
  177. prvCamera.NewDataFlag = 1;
  178. if (prvCamera.CaptureMode){
  179. if (!pData){
  180. if (prvCamera.CaptureWait && prvCamera.JPEGEncodeDone)
  181. {
  182. prvCamera.CaptureWait = 0;
  183. prvCamera.JPEGEncodeDone = 0;
  184. Core_EncodeJPEGStart(prvCamera.Width, prvCamera.Height, prvCamera.JPEGQuality);
  185. }
  186. else if (!prvCamera.CaptureWait)
  187. {
  188. prvCamera.CaptureWait = 1;
  189. prvCamera.JPEGEncodeDone = 0;
  190. Core_EncodeJPEGEnd(Camera_SaveJPEGDone, 0);
  191. }
  192. }
  193. else
  194. {
  195. if (!prvCamera.CaptureWait)
  196. {
  197. uint8_t *data = malloc(RxBuf->MaxLen * 4);
  198. memcpy(data, RxBuf->Data, RxBuf->MaxLen * 4);
  199. Core_EncodeJPEGRun(data, RxBuf->MaxLen * 4, zbar_scan?COLOR_MODE_GRAY:COLOR_MODE_RGB_565);
  200. }
  201. }
  202. return 0;
  203. }
  204. if (zbar_scan == 0){
  205. if (!pData){
  206. prvCamera.VLen = 0;
  207. return 0;
  208. }
  209. if (prvCamera.DrawLCD)
  210. {
  211. Camera_DrawLcd(RxBuf->Data, zbar_scan);
  212. }
  213. prvCamera.VLen += prvCamera.drawVLen;
  214. return 0;
  215. }else if (zbar_scan == 1){
  216. Buffer_Struct *RxBuf = (Buffer_Struct *)pData;
  217. if (!pData)
  218. {
  219. if (!prvCamera.DataCache && !prvCamera.IsDecoding)
  220. {
  221. prvCamera.DataCache = malloc(prvCamera.TotalSize);
  222. }
  223. else if (prvCamera.DataCache)
  224. {
  225. if (prvCamera.DrawLCD) {
  226. Camera_DrawLcd(prvCamera.DataCache, zbar_scan);
  227. }
  228. Core_DecodeQR(prvCamera.DataCache, prvCamera.Width, prvCamera.Height, DecodeQR_CBDataFun);
  229. prvCamera.DataCache = NULL;
  230. prvCamera.IsDecoding = 1;
  231. }
  232. prvCamera.CurSize = 0;
  233. return 0;
  234. }
  235. if (prvCamera.DataCache)
  236. {
  237. memcpy(&prvCamera.DataCache[prvCamera.CurSize], RxBuf->Data, RxBuf->MaxLen * 4);
  238. prvCamera.CurSize += RxBuf->MaxLen * 4;
  239. if (prvCamera.TotalSize < prvCamera.CurSize){
  240. DBG_ERR("%d,%d", prvCamera.TotalSize, prvCamera.CurSize);
  241. prvCamera.CurSize = 0;
  242. }
  243. }
  244. return 0;
  245. }
  246. }
  247. int luat_camera_init(luat_camera_conf_t *conf){
  248. int error = ERROR_NONE;
  249. GPIO_Iomux(GPIOD_01, 3);
  250. GPIO_Iomux(GPIOD_02, 3);
  251. GPIO_Iomux(GPIOD_03, 3);
  252. GPIO_Iomux(GPIOD_08, 3);
  253. GPIO_Iomux(GPIOD_09, 3);
  254. GPIO_Iomux(GPIOD_10, 3);
  255. GPIO_Iomux(GPIOD_11, 3);
  256. GPIO_Iomux(GPIOE_00, 3);
  257. GPIO_Iomux(GPIOE_01, 3);
  258. GPIO_Iomux(GPIOE_02, 3);
  259. GPIO_Iomux(GPIOE_03, 3);
  260. if (!prvCamera.CheckTimer)
  261. {
  262. prvCamera.CheckTimer = Timer_Create(prvCamera_DataTimeout, NULL, NULL);
  263. }
  264. else
  265. {
  266. Timer_Stop(prvCamera.CheckTimer);
  267. }
  268. memcpy(&camera_conf, conf, sizeof(luat_camera_conf_t));
  269. lcd_conf = conf->lcd_conf;
  270. prvCamera.DrawLCD = conf->draw_lcd;
  271. if (lcd_conf)
  272. {
  273. prvCamera.Width = lcd_conf->w;
  274. prvCamera.Height = lcd_conf->h;
  275. }
  276. else
  277. {
  278. prvCamera.Width = camera_conf.sensor_width;
  279. prvCamera.Height = camera_conf.sensor_height;
  280. prvCamera.DrawLCD = 0;
  281. }
  282. if (conf->zbar_scan == 1){
  283. prvCamera.DataCache = NULL;
  284. prvCamera.TotalSize = prvCamera.Width * prvCamera.Height;
  285. prvCamera.DataBytes = 1;
  286. }
  287. GPIO_Iomux(GPIOA_05, 2);
  288. HWTimer_SetPWM(conf->pwm_id, conf->pwm_period, conf->pwm_pulse, 0);
  289. prvCamera.PWMID = conf->pwm_id;
  290. luat_i2c_setup(conf->i2c_id,1,NULL);
  291. for(size_t i = 0; i < conf->init_cmd_size; i++){
  292. if (luat_i2c_send(conf->i2c_id, conf->i2c_addr, &(conf->init_cmd[i]), 2,1))
  293. {
  294. error = -ERROR_OPERATION_FAILED;
  295. }
  296. i++;
  297. }
  298. prvCamera.I2CID = conf->i2c_id;
  299. DCMI_Setup(0, 0, 0, 8, 0);
  300. DCMI_SetCallback(prvCamera_DCMICB, conf->zbar_scan);
  301. // if (conf->zbar_scan == 0){
  302. // DCMI_SetCROPConfig(1, (conf->sensor_height-lcd_conf->h)/2, ((conf->sensor_width-lcd_conf->w)/2)*2, lcd_conf->h - 1, 2*lcd_conf->w - 1);
  303. // DCMI_CaptureSwitch(1, 0,lcd_conf->w, lcd_conf->h, 2, &prvCamera.drawVLen);
  304. // prvCamera.VLen = 0;
  305. // }else if(conf->zbar_scan == 1){
  306. // DCMI_SetCROPConfig(1, (conf->sensor_height-prvCamera.Height)/2, ((conf->sensor_width-prvCamera.Width)/2)*prvCamera.DataBytes, prvCamera.Height - 1, prvCamera.DataBytes*prvCamera.Width - 1);
  307. // DCMI_CaptureSwitch(1, 0,lcd_conf->w, lcd_conf->h, prvCamera.DataBytes, &prvCamera.drawVLen);
  308. // }
  309. return error;
  310. }
  311. int luat_camera_start(int id)
  312. {
  313. DCMI_SetCallback(prvCamera_DCMICB, camera_conf.zbar_scan);
  314. if (prvCamera.DataCache)
  315. {
  316. DCMI_CaptureSwitch(0, 0, 0, 0, 0, NULL);
  317. free(prvCamera.DataCache);
  318. }
  319. if (camera_conf.zbar_scan == 0){
  320. if (lcd_conf)
  321. {
  322. DCMI_SetCROPConfig(1, (camera_conf.sensor_height-lcd_conf->h)/2, ((camera_conf.sensor_width-lcd_conf->w)/2)*2, lcd_conf->h - 1, 2*lcd_conf->w - 1);
  323. DCMI_CaptureSwitch(1, 0, lcd_conf->w, lcd_conf->h, 2, &prvCamera.drawVLen);
  324. }
  325. else
  326. {
  327. DCMI_SetCROPConfig(0, 0, 0, 0, 0);
  328. DCMI_CaptureSwitch(1, 0, camera_conf.sensor_width, camera_conf.sensor_height, 2, &prvCamera.drawVLen);
  329. }
  330. prvCamera.CaptureMode = 0;
  331. prvCamera.VLen = 0;
  332. }else if(camera_conf.zbar_scan == 1){
  333. if (lcd_conf)
  334. {
  335. DCMI_SetCROPConfig(1, (camera_conf.sensor_height-prvCamera.Height)/2, ((camera_conf.sensor_width-prvCamera.Width)/2)*prvCamera.DataBytes, prvCamera.Height - 1, prvCamera.DataBytes*prvCamera.Width - 1);
  336. DCMI_CaptureSwitch(1, 0,lcd_conf->w, lcd_conf->h, prvCamera.DataBytes, &prvCamera.drawVLen);
  337. }
  338. else
  339. {
  340. DCMI_SetCROPConfig(0, 0, 0, 0, 0);
  341. DCMI_CaptureSwitch(1, 0, camera_conf.sensor_width, camera_conf.sensor_height, prvCamera.DataBytes, &prvCamera.drawVLen);
  342. }
  343. }
  344. prvCamera.NewDataFlag = 0;
  345. Timer_StartMS(prvCamera.CheckTimer, 1000, 1);
  346. return 0;
  347. }
  348. int luat_camera_capture(int id, uint8_t quality, const char *path)
  349. {
  350. DCMI_CaptureSwitch(0, 0, 0, 0, 0, NULL);
  351. if (prvCamera.DataCache)
  352. {
  353. free(prvCamera.DataCache);
  354. prvCamera.DataCache = NULL;
  355. }
  356. if (path)
  357. {
  358. OS_ReInitBuffer(&prvCamera.JPEGSavePath, strlen(path) + 1);
  359. memcpy(prvCamera.JPEGSavePath.Data, path, strlen(path));
  360. }
  361. OS_ReInitBuffer(&prvCamera.FileBuffer, 16 * 1024);
  362. Core_EncodeJPEGSetup(Camera_SaveJPEGData, &prvCamera.FileBuffer);
  363. luat_camera_start(id);
  364. prvCamera.JPEGQuality = quality;
  365. prvCamera.CaptureMode = 1;
  366. prvCamera.CaptureWait = 1;
  367. prvCamera.JPEGEncodeDone = 1;
  368. Timer_StartMS(prvCamera.CheckTimer, 1000, 1);
  369. return 0;
  370. }
  371. static voidpf luat_zip_zalloc( voidpf opaque, uint32_t items, uint32_t size)
  372. {
  373. voidpf *p = zalloc(items * size);
  374. return p;
  375. }
  376. static void luat_zip_free (voidpf opaque, voidpf ptr)
  377. {
  378. free(ptr);
  379. }
  380. static int luat_camera_video_zip(void *data ,void *param)
  381. {
  382. PV_Union uPV;
  383. uPV.p = param;
  384. int ret;
  385. unsigned have;
  386. z_stream strm;
  387. prvCamera.VideoCache[0] = 'V';
  388. prvCamera.VideoCache[1] = 'C';
  389. prvCamera.VideoCache[2] = 'A';
  390. prvCamera.VideoCache[3] = 'M';
  391. BytesPutLe16(prvCamera.VideoCache + 4, prvCamera.Width);
  392. BytesPutLe16(prvCamera.VideoCache + 6, prvCamera.Height);
  393. BytesPutLe32(prvCamera.VideoCache + 8, uPV.u16[1]);
  394. {
  395. if ((prvCamera.CurSize + (prvCamera.Height - uPV.u16[1]) * prvCamera.Width * 2) < (800 * (GetSysTickMS() - prvCamera.StartTick)))
  396. {
  397. BytesPutLe16(prvCamera.VideoCache + 12, uPV.u16[0]);
  398. BytesPutLe16(prvCamera.VideoCache + 14, uPV.u16[0]);
  399. memcpy(prvCamera.VideoCache + 16, data, uPV.u16[0]);
  400. free(data);
  401. Core_VUartBufferTx(VIRTUAL_UART0, prvCamera.VideoCache, uPV.u16[0] + 16);
  402. prvCamera.CurSize += uPV.u16[0];
  403. return 0;
  404. }
  405. }
  406. strm.zalloc = NULL;
  407. strm.zfree = NULL;
  408. ret = deflateInit2_(&strm, 1, Z_DEFLATED, 12, 6,
  409. Z_DEFAULT_STRATEGY, ZLIB_VERSION, (int)sizeof(z_stream));
  410. if (Z_OK == ret)
  411. {
  412. strm.next_in = data;
  413. strm.avail_in = uPV.u16[0];
  414. strm.avail_out = 10240;
  415. strm.next_out = prvCamera.VideoCache + 16;
  416. ret = deflate(&strm, Z_FINISH); /* no bad return value */
  417. have = 10240 - strm.avail_out;
  418. deflateEnd(&strm);
  419. BytesPutLe16(prvCamera.VideoCache + 12, uPV.u16[0]);
  420. BytesPutLe16(prvCamera.VideoCache + 14, have);
  421. free(data);
  422. Core_VUartBufferTx(VIRTUAL_UART0, prvCamera.VideoCache, have + 16);
  423. prvCamera.CurSize += have;
  424. }
  425. else
  426. {
  427. DBG("%d", ret);
  428. free(data);
  429. }
  430. }
  431. static int luat_camera_video_zip_done(void *data ,void *param)
  432. {
  433. prvCamera.CaptureWait = 0;
  434. // DBG("%u", prvCamera.CurSize);
  435. prvCamera.CurSize = 0;
  436. }
  437. static int luat_camera_video_cb(void *pdata ,void *param)
  438. {
  439. Buffer_Struct *RxBuf = (Buffer_Struct *)pdata;
  440. prvCamera.NewDataFlag = 1;
  441. if (!pdata){
  442. if (prvCamera.JPEGEncodeDone)
  443. {
  444. prvCamera.JPEGEncodeDone = 0;
  445. prvCamera.CaptureWait = 1;
  446. Core_ServiceRunUserAPI(luat_camera_video_zip_done, NULL, NULL);
  447. }
  448. prvCamera.VLen = 0;
  449. }
  450. else
  451. {
  452. if ((!prvCamera.VLen || prvCamera.JPEGEncodeDone) && !prvCamera.CaptureWait)
  453. {
  454. if (!prvCamera.VLen)
  455. {
  456. prvCamera.StartTick = GetSysTickMS();
  457. }
  458. prvCamera.JPEGEncodeDone = 1;
  459. uint8_t *data = malloc(RxBuf->MaxLen * 4);
  460. if (data)
  461. {
  462. memcpy(data, RxBuf->Data, RxBuf->MaxLen * 4);
  463. PV_Union uPV;
  464. uPV.u16[0] = RxBuf->MaxLen * 4;
  465. uPV.u16[1] = prvCamera.VLen;
  466. Core_ServiceRunUserAPI(luat_camera_video_zip, data, uPV.u32);
  467. }
  468. else
  469. {
  470. DBG("no mem");
  471. Core_PrintMemInfo();
  472. }
  473. }
  474. prvCamera.VLen += prvCamera.drawVLen;
  475. }
  476. return 0;
  477. }
  478. int luat_camera_video(int id, int w, int h, uint8_t uart_id)
  479. {
  480. uint8_t data_byte = camera_conf.zbar_scan?1:2;
  481. Timer_Stop(prvCamera.CheckTimer);
  482. OS_DeInitBuffer(&prvCamera.FileBuffer);
  483. DCMI_SetCallback(luat_camera_video_cb, 0);
  484. if (prvCamera.DataCache)
  485. {
  486. DCMI_CaptureSwitch(0, 0, 0, 0, 0, NULL);
  487. free(prvCamera.DataCache);
  488. prvCamera.DataCache = NULL;
  489. }
  490. if (prvCamera.VideoCache)
  491. {
  492. luat_vm_free(prvCamera.VideoCache);
  493. }
  494. prvCamera.VideoCache = luat_vm_malloc(10240 + 96);
  495. DCMI_SetCROPConfig(1, (camera_conf.sensor_height-h) >> 1, ((camera_conf.sensor_width-w) >> 1)*data_byte, h - 1, data_byte*w- 1);
  496. DCMI_CaptureSwitch(1, w * data_byte * 4, 0, 0, 0, &prvCamera.drawVLen);
  497. prvCamera.drawVLen = 16;
  498. prvCamera.CaptureWait = 0;
  499. prvCamera.VLen = 0;
  500. prvCamera.Width = w;
  501. prvCamera.Height = h;
  502. Timer_StartMS(prvCamera.CheckTimer, 1000, 1);
  503. }
  504. static int luat_camera_get_raw_cb(void *pdata ,void *param)
  505. {
  506. Buffer_Struct *RxBuf = (Buffer_Struct *)pdata;
  507. prvCamera.NewDataFlag = 1;
  508. if (!pdata){
  509. if (prvCamera.RawBuffer.Pos)
  510. {
  511. if (!prvCamera.CaptureWait)
  512. {
  513. prvCamera.CaptureWait = 1;//阻塞住,等到用户层处理完成
  514. rtos_msg_t msg = {0};
  515. {
  516. msg.handler = l_camera_handler;
  517. msg.ptr = NULL;
  518. msg.arg1 = 0;
  519. msg.arg2 = prvCamera.RawBuffer.Pos;
  520. luat_msgbus_put(&msg, 1);
  521. }
  522. }
  523. }
  524. else
  525. {
  526. prvCamera.CaptureWait = 0;
  527. }
  528. prvCamera.VLen = 0;
  529. }
  530. else
  531. {
  532. if (!prvCamera.CaptureWait)
  533. {
  534. Buffer_StaticWrite(&prvCamera.RawBuffer, RxBuf->Data, RxBuf->MaxLen * 4);
  535. }
  536. prvCamera.VLen += prvCamera.drawVLen;
  537. }
  538. return 0;
  539. }
  540. int luat_camera_get_raw_start(int id, int w, int h, uint8_t *buf, uint32_t max_len)
  541. {
  542. uint8_t data_byte = camera_conf.zbar_scan?1:2;
  543. Timer_Stop(prvCamera.CheckTimer);
  544. OS_DeInitBuffer(&prvCamera.FileBuffer);
  545. DCMI_SetCallback(luat_camera_get_raw_cb, 0);
  546. if (prvCamera.DataCache)
  547. {
  548. DCMI_CaptureSwitch(0, 0, 0, 0, 0, NULL);
  549. free(prvCamera.DataCache);
  550. prvCamera.DataCache = NULL;
  551. }
  552. if (prvCamera.VideoCache)
  553. {
  554. luat_vm_free(prvCamera.VideoCache);
  555. }
  556. Buffer_StaticInit(&prvCamera.RawBuffer, buf, max_len);
  557. DCMI_SetCROPConfig(1, (camera_conf.sensor_height-h) >> 1, ((camera_conf.sensor_width-w) >> 1)*data_byte, h - 1, data_byte*w- 1);
  558. DCMI_CaptureSwitch(1, w * data_byte * 4, 0, 0, 0, &prvCamera.drawVLen);
  559. prvCamera.drawVLen = 16;
  560. prvCamera.CaptureWait = 0;
  561. prvCamera.VLen = 0;
  562. prvCamera.Width = w;
  563. prvCamera.Height = h;
  564. Timer_StartMS(prvCamera.CheckTimer, 1000, 1);
  565. }
  566. int luat_camera_get_raw_again(int id)
  567. {
  568. prvCamera.RawBuffer.Pos = 0;
  569. }
  570. int luat_camera_stop(int id)
  571. {
  572. Timer_Stop(prvCamera.CheckTimer);
  573. DCMI_CaptureSwitch(0, 0, 0, 0, 0, NULL);
  574. if (prvCamera.DataCache)
  575. {
  576. free(prvCamera.DataCache);
  577. prvCamera.DataCache = NULL;
  578. }
  579. OS_DeInitBuffer(&prvCamera.FileBuffer);
  580. if (prvCamera.VideoCache)
  581. {
  582. luat_vm_free(prvCamera.VideoCache);
  583. prvCamera.VideoCache = NULL;
  584. }
  585. return 0;
  586. }
  587. int luat_camera_close(int id)
  588. {
  589. luat_camera_stop(id);
  590. GPIO_Iomux(GPIOD_01, 1);
  591. GPIO_Iomux(GPIOD_02, 1);
  592. GPIO_Iomux(GPIOD_03, 1);
  593. GPIO_Iomux(GPIOD_08, 1);
  594. GPIO_Iomux(GPIOD_09, 1);
  595. GPIO_Iomux(GPIOD_10, 1);
  596. GPIO_Iomux(GPIOD_11, 1);
  597. GPIO_Iomux(GPIOE_00, 1);
  598. GPIO_Iomux(GPIOE_01, 1);
  599. GPIO_Iomux(GPIOE_02, 1);
  600. GPIO_Iomux(GPIOA_05, 1);
  601. HWTimer_Stop(prvCamera.PWMID);
  602. luat_i2c_close(prvCamera.I2CID);
  603. }