luat_camera_air105.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  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 "app_interface.h"
  22. #include "luat_base.h"
  23. #include "luat_lcd.h"
  24. #include "luat_camera.h"
  25. #include "luat_msgbus.h"
  26. #include "luat_spi.h"
  27. #include "luat_gpio.h"
  28. #include "app_interface.h"
  29. #include "zbar.h"
  30. #include "symbol.h"
  31. #include "image.h"
  32. #define LUAT_LOG_TAG "camera"
  33. #include "luat_log.h"
  34. typedef struct
  35. {
  36. Buffer_Struct FileBuffer;
  37. Buffer_Struct JPEGSavePath;
  38. Timer_t *CheckTimer;
  39. uint8_t *DataCache;
  40. uint32_t TotalSize;
  41. uint32_t CurSize;
  42. uint32_t VLen;
  43. uint32_t drawVLen;
  44. uint16_t Width;
  45. uint16_t Height;
  46. uint8_t DataBytes;
  47. uint8_t IsDecoding;
  48. uint8_t JPEGQuality;
  49. uint8_t CaptureMode;
  50. uint8_t CaptureWait;
  51. uint8_t JPEGEncodeDone;
  52. uint8_t PWMID;
  53. uint8_t I2CID;
  54. uint8_t NewDataFlag;
  55. }Camera_CtrlStruct;
  56. static Camera_CtrlStruct prvCamera;
  57. static struct luat_camera_conf camera_conf;
  58. static luat_lcd_conf_t* lcd_conf;
  59. static uint8_t draw_lcd = 0;
  60. static int32_t prvCamera_DataTimeout(void *pData, void *pParam)
  61. {
  62. if (!prvCamera.NewDataFlag)
  63. {
  64. rtos_msg_t msg = {0};
  65. {
  66. msg.handler = l_camera_handler;
  67. msg.ptr = NULL;
  68. msg.arg1 = 0;
  69. msg.arg2 = 0;
  70. luat_msgbus_put(&msg, 1);
  71. }
  72. }
  73. prvCamera.NewDataFlag = 0;
  74. }
  75. static void Camera_SaveJPEGData(void *Cxt, void *pData, int Size)
  76. {
  77. OS_BufferWrite(Cxt, pData, Size);
  78. }
  79. static int32_t Camera_SaveJPEGDone(void *pData, void *pParam)
  80. {
  81. HANDLE fd;
  82. if (prvCamera.JPEGSavePath.Data)
  83. {
  84. fd = luat_fs_fopen(prvCamera.JPEGSavePath.Data, "w");
  85. }
  86. else
  87. {
  88. fd = luat_fs_fopen("/capture.jpg", "w");
  89. }
  90. if (fd)
  91. {
  92. LLOGD("capture data %ubyte", luat_fs_fwrite(prvCamera.FileBuffer.Data, prvCamera.FileBuffer.Pos, 1, fd));
  93. luat_fs_fclose(fd);
  94. }
  95. OS_DeInitBuffer(&prvCamera.FileBuffer);
  96. prvCamera.CaptureWait = 1;
  97. prvCamera.JPEGEncodeDone = 1;
  98. prvCamera.CaptureMode = 0;
  99. Core_EncodeJPEGSetup(NULL, &prvCamera);
  100. rtos_msg_t msg = {0};
  101. {
  102. msg.handler = l_camera_handler;
  103. msg.ptr = NULL;
  104. msg.arg1 = 0;
  105. msg.arg2 = 1;
  106. luat_msgbus_put(&msg, 1);
  107. }
  108. }
  109. void DecodeQR_CBDataFun(uint8_t *Data, uint32_t Len){
  110. prvCamera.IsDecoding = 0;
  111. rtos_msg_t msg = {0};
  112. if (Data){
  113. msg.handler = l_camera_handler;
  114. msg.ptr = Data;
  115. msg.arg1 = 0;
  116. msg.arg2 = Len;
  117. luat_msgbus_put(&msg, 1);
  118. }
  119. }
  120. static int32_t Camera_DrawLcd(void *DrawData, uint8_t Scan){
  121. LCD_DrawStruct *draw = OS_Malloc(sizeof(LCD_DrawStruct));
  122. if (!draw){
  123. DBG("lcd flush no memory");
  124. return -1;
  125. }
  126. uint8_t CPHA = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.CPHA;
  127. uint8_t CPOL = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.CPOL;
  128. draw->DCDelay = lcd_conf->dc_delay_us;
  129. draw->Mode = SPI_MODE_0;
  130. if(CPHA&&CPOL)draw->Mode = SPI_MODE_3;
  131. else if(CPOL)draw->Mode = SPI_MODE_2;
  132. else if(CPHA)draw->Mode = SPI_MODE_1;
  133. draw->Speed = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.bandrate;
  134. if (((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->bus_id == 5) draw->SpiID = HSPI_ID0;
  135. else draw->SpiID = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->bus_id;
  136. draw->CSPin = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.cs;
  137. draw->DCPin = lcd_conf->pin_dc;
  138. draw->xoffset = lcd_conf->xoffset;
  139. draw->yoffset = lcd_conf->yoffset;
  140. if (Scan == 0){
  141. draw->x1 = 0;
  142. draw->x2 = lcd_conf->w -1;
  143. draw->y1 = prvCamera.VLen;
  144. draw->y2 = prvCamera.VLen + prvCamera.drawVLen -1;
  145. draw->Size = (draw->x2 - draw->x1 + 1) * (draw->y2 - draw->y1 + 1) * 2;
  146. draw->ColorMode = COLOR_MODE_RGB_565;
  147. draw->Data = OS_Malloc(draw->Size);
  148. if (!draw->Data){
  149. DBG("lcd flush data no memory");
  150. OS_Free(draw);
  151. return -1;
  152. }
  153. memcpy(draw->Data, DrawData, draw->Size);
  154. Core_LCDDraw(draw);
  155. }else if(Scan == 1){
  156. draw->x1 = 0;
  157. draw->x2 = prvCamera.Width - 1;
  158. draw->y1 = 0;
  159. draw->y2 = prvCamera.Height - 1;
  160. draw->Size = prvCamera.TotalSize;
  161. draw->ColorMode = COLOR_MODE_GRAY;
  162. draw->Data = DrawData;
  163. Core_CameraDraw(draw);
  164. }else{
  165. DBG("Scan error");
  166. OS_Free(draw);
  167. return -1;
  168. }
  169. }
  170. static int32_t prvCamera_DCMICB(void *pData, void *pParam){
  171. uint8_t zbar_scan = (uint8_t)pParam;
  172. Buffer_Struct *RxBuf = (Buffer_Struct *)pData;
  173. prvCamera.NewDataFlag = 1;
  174. if (prvCamera.CaptureMode){
  175. if (!pData){
  176. if (prvCamera.CaptureWait && prvCamera.JPEGEncodeDone)
  177. {
  178. prvCamera.CaptureWait = 0;
  179. prvCamera.JPEGEncodeDone = 0;
  180. Core_EncodeJPEGStart(prvCamera.Width, prvCamera.Height, prvCamera.JPEGQuality);
  181. }
  182. else if (!prvCamera.CaptureWait)
  183. {
  184. prvCamera.CaptureWait = 1;
  185. prvCamera.JPEGEncodeDone = 0;
  186. Core_EncodeJPEGEnd(Camera_SaveJPEGDone, 0);
  187. }
  188. }
  189. else
  190. {
  191. if (!prvCamera.CaptureWait)
  192. {
  193. uint8_t *data = malloc(RxBuf->MaxLen * 4);
  194. memcpy(data, RxBuf->Data, RxBuf->MaxLen * 4);
  195. Core_EncodeJPEGRun(data, RxBuf->MaxLen * 4, zbar_scan?COLOR_MODE_GRAY:COLOR_MODE_RGB_565);
  196. }
  197. }
  198. return 0;
  199. }
  200. if (zbar_scan == 0){
  201. if (!pData){
  202. prvCamera.VLen = 0;
  203. return 0;
  204. }
  205. if (draw_lcd)
  206. {
  207. Camera_DrawLcd(RxBuf->Data, zbar_scan);
  208. }
  209. prvCamera.VLen += prvCamera.drawVLen;
  210. return 0;
  211. }else if (zbar_scan == 1){
  212. Buffer_Struct *RxBuf = (Buffer_Struct *)pData;
  213. if (!pData)
  214. {
  215. if (!prvCamera.DataCache && !prvCamera.IsDecoding)
  216. {
  217. prvCamera.DataCache = malloc(prvCamera.TotalSize);
  218. }
  219. else if (prvCamera.DataCache)
  220. {
  221. if (draw_lcd) {
  222. Camera_DrawLcd(prvCamera.DataCache, zbar_scan);
  223. }
  224. Core_DecodeQR(prvCamera.DataCache, prvCamera.Width, prvCamera.Height, DecodeQR_CBDataFun);
  225. prvCamera.DataCache = NULL;
  226. prvCamera.IsDecoding = 1;
  227. }
  228. prvCamera.CurSize = 0;
  229. return 0;
  230. }
  231. if (prvCamera.DataCache)
  232. {
  233. memcpy(&prvCamera.DataCache[prvCamera.CurSize], RxBuf->Data, RxBuf->MaxLen * 4);
  234. prvCamera.CurSize += RxBuf->MaxLen * 4;
  235. if (prvCamera.TotalSize < prvCamera.CurSize){
  236. DBG_ERR("%d,%d", prvCamera.TotalSize, prvCamera.CurSize);
  237. prvCamera.CurSize = 0;
  238. }
  239. }
  240. return 0;
  241. }
  242. }
  243. int luat_camera_init(luat_camera_conf_t *conf){
  244. int error = ERROR_NONE;
  245. GPIO_Iomux(GPIOD_01, 3);
  246. GPIO_Iomux(GPIOD_02, 3);
  247. GPIO_Iomux(GPIOD_03, 3);
  248. GPIO_Iomux(GPIOD_08, 3);
  249. GPIO_Iomux(GPIOD_09, 3);
  250. GPIO_Iomux(GPIOD_10, 3);
  251. GPIO_Iomux(GPIOD_11, 3);
  252. GPIO_Iomux(GPIOE_00, 3);
  253. GPIO_Iomux(GPIOE_01, 3);
  254. GPIO_Iomux(GPIOE_02, 3);
  255. GPIO_Iomux(GPIOE_03, 3);
  256. if (!prvCamera.CheckTimer)
  257. {
  258. prvCamera.CheckTimer = Timer_Create(prvCamera_DataTimeout, NULL, NULL);
  259. }
  260. else
  261. {
  262. Timer_Stop(prvCamera.CheckTimer);
  263. }
  264. memcpy(&camera_conf, conf, sizeof(luat_camera_conf_t));
  265. lcd_conf = conf->lcd_conf;
  266. draw_lcd = conf->draw_lcd;
  267. if (lcd_conf)
  268. {
  269. prvCamera.Width = lcd_conf->w;
  270. prvCamera.Height = lcd_conf->h;
  271. }
  272. else
  273. {
  274. prvCamera.Width = camera_conf.sensor_width;
  275. prvCamera.Height = camera_conf.sensor_height;
  276. draw_lcd = 0;
  277. }
  278. if (conf->zbar_scan == 1){
  279. prvCamera.DataCache = NULL;
  280. prvCamera.TotalSize = prvCamera.Width * prvCamera.Height;
  281. prvCamera.DataBytes = 1;
  282. }
  283. GPIO_Iomux(GPIOA_05, 2);
  284. HWTimer_SetPWM(conf->pwm_id, conf->pwm_period, conf->pwm_pulse, 0);
  285. prvCamera.PWMID = conf->pwm_id;
  286. luat_i2c_setup(conf->i2c_id,1,NULL);
  287. for(size_t i = 0; i < conf->init_cmd_size; i++){
  288. if (luat_i2c_send(conf->i2c_id, conf->i2c_addr, &(conf->init_cmd[i]), 2,1))
  289. {
  290. error = -ERROR_OPERATION_FAILED;
  291. }
  292. i++;
  293. }
  294. prvCamera.I2CID = conf->i2c_id;
  295. DCMI_Setup(0, 0, 0, 8, 0);
  296. DCMI_SetCallback(prvCamera_DCMICB, conf->zbar_scan);
  297. // if (conf->zbar_scan == 0){
  298. // 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);
  299. // DCMI_CaptureSwitch(1, 0,lcd_conf->w, lcd_conf->h, 2, &prvCamera.drawVLen);
  300. // prvCamera.VLen = 0;
  301. // }else if(conf->zbar_scan == 1){
  302. // 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);
  303. // DCMI_CaptureSwitch(1, 0,lcd_conf->w, lcd_conf->h, prvCamera.DataBytes, &prvCamera.drawVLen);
  304. // }
  305. return error;
  306. }
  307. int luat_camera_start(int id)
  308. {
  309. if (prvCamera.DataCache)
  310. {
  311. DCMI_CaptureSwitch(0, 0, 0, 0, 0, NULL);
  312. free(prvCamera.DataCache);
  313. }
  314. if (camera_conf.zbar_scan == 0){
  315. if (lcd_conf)
  316. {
  317. 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);
  318. DCMI_CaptureSwitch(1, 0, lcd_conf->w, lcd_conf->h, 2, &prvCamera.drawVLen);
  319. }
  320. else
  321. {
  322. DCMI_SetCROPConfig(0, 0, 0, 0, 0);
  323. DCMI_CaptureSwitch(1, 0, camera_conf.sensor_width, camera_conf.sensor_height, 2, &prvCamera.drawVLen);
  324. }
  325. prvCamera.CaptureMode = 0;
  326. prvCamera.VLen = 0;
  327. }else if(camera_conf.zbar_scan == 1){
  328. if (lcd_conf)
  329. {
  330. 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);
  331. DCMI_CaptureSwitch(1, 0,lcd_conf->w, lcd_conf->h, prvCamera.DataBytes, &prvCamera.drawVLen);
  332. }
  333. else
  334. {
  335. DCMI_SetCROPConfig(0, 0, 0, 0, 0);
  336. DCMI_CaptureSwitch(1, 0, camera_conf.sensor_width, camera_conf.sensor_height, prvCamera.DataBytes, &prvCamera.drawVLen);
  337. }
  338. }
  339. prvCamera.NewDataFlag = 0;
  340. Timer_StartMS(prvCamera.CheckTimer, 1000, 1);
  341. return 0;
  342. }
  343. int luat_camera_capture(int id, uint8_t quality, const char *path)
  344. {
  345. DCMI_CaptureSwitch(0, 0, 0, 0, 0, NULL);
  346. if (prvCamera.DataCache)
  347. {
  348. free(prvCamera.DataCache);
  349. prvCamera.DataCache = NULL;
  350. }
  351. if (path)
  352. {
  353. OS_ReInitBuffer(&prvCamera.JPEGSavePath, strlen(path) + 1);
  354. memcpy(prvCamera.JPEGSavePath.Data, path, strlen(path));
  355. }
  356. OS_ReInitBuffer(&prvCamera.FileBuffer, 16 * 1024);
  357. Core_EncodeJPEGSetup(Camera_SaveJPEGData, &prvCamera);
  358. luat_camera_start(id);
  359. prvCamera.JPEGQuality = quality;
  360. prvCamera.CaptureMode = 1;
  361. prvCamera.CaptureWait = 1;
  362. prvCamera.JPEGEncodeDone = 1;
  363. Timer_StartMS(prvCamera.CheckTimer, 1000, 1);
  364. return 0;
  365. }
  366. int luat_camera_stop(int id)
  367. {
  368. Timer_Stop(prvCamera.CheckTimer);
  369. DCMI_CaptureSwitch(0, 0, 0, 0, 0, NULL);
  370. if (prvCamera.DataCache)
  371. {
  372. free(prvCamera.DataCache);
  373. prvCamera.DataCache = NULL;
  374. }
  375. OS_DeInitBuffer(&prvCamera.FileBuffer);
  376. return 0;
  377. }
  378. int luat_camera_close(int id)
  379. {
  380. luat_camera_stop(id);
  381. GPIO_Iomux(GPIOD_01, 1);
  382. GPIO_Iomux(GPIOD_02, 1);
  383. GPIO_Iomux(GPIOD_03, 1);
  384. GPIO_Iomux(GPIOD_08, 1);
  385. GPIO_Iomux(GPIOD_09, 1);
  386. GPIO_Iomux(GPIOD_10, 1);
  387. GPIO_Iomux(GPIOD_11, 1);
  388. GPIO_Iomux(GPIOE_00, 1);
  389. GPIO_Iomux(GPIOE_01, 1);
  390. GPIO_Iomux(GPIOE_02, 1);
  391. GPIO_Iomux(GPIOA_05, 1);
  392. HWTimer_Stop(prvCamera.PWMID);
  393. luat_i2c_close(prvCamera.I2CID);
  394. }