| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- /*
- * Copyright (c) 2022 OpenLuat & AirM2M
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- #include "app_interface.h"
- #include "luat_base.h"
- #include "luat_lcd.h"
- #include "luat_camera.h"
- #include "luat_msgbus.h"
- #include "luat_spi.h"
- #include "luat_gpio.h"
- #include "app_interface.h"
- #include "zbar.h"
- #include "symbol.h"
- #include "image.h"
- #define LUAT_LOG_TAG "camera"
- #include "luat_log.h"
- typedef struct
- {
- Buffer_Struct FileBuffer;
- Buffer_Struct JPEGSavePath;
- Timer_t *CheckTimer;
- uint8_t *DataCache;
- uint32_t TotalSize;
- uint32_t CurSize;
- uint32_t VLen;
- uint32_t drawVLen;
- uint16_t Width;
- uint16_t Height;
- uint8_t DataBytes;
- uint8_t IsDecoding;
- uint8_t JPEGQuality;
- uint8_t CaptureMode;
- uint8_t CaptureWait;
- uint8_t JPEGEncodeDone;
- uint8_t PWMID;
- uint8_t I2CID;
- uint8_t NewDataFlag;
- }Camera_CtrlStruct;
- static Camera_CtrlStruct prvCamera;
- static struct luat_camera_conf camera_conf;
- static luat_lcd_conf_t* lcd_conf;
- static uint8_t draw_lcd = 0;
- static int32_t prvCamera_DataTimeout(void *pData, void *pParam)
- {
- if (!prvCamera.NewDataFlag)
- {
- rtos_msg_t msg = {0};
- {
- msg.handler = l_camera_handler;
- msg.ptr = NULL;
- msg.arg1 = 0;
- msg.arg2 = 0;
- luat_msgbus_put(&msg, 1);
- }
- }
- prvCamera.NewDataFlag = 0;
- }
- static void Camera_SaveJPEGData(void *Cxt, void *pData, int Size)
- {
- OS_BufferWrite(Cxt, pData, Size);
- }
- static int32_t Camera_SaveJPEGDone(void *pData, void *pParam)
- {
- HANDLE fd;
- if (prvCamera.JPEGSavePath.Data)
- {
- fd = luat_fs_fopen(prvCamera.JPEGSavePath.Data, "w");
- }
- else
- {
- fd = luat_fs_fopen("/capture.jpg", "w");
- }
- if (fd)
- {
- LLOGD("capture data %ubyte", luat_fs_fwrite(prvCamera.FileBuffer.Data, prvCamera.FileBuffer.Pos, 1, fd));
- luat_fs_fclose(fd);
- }
- OS_DeInitBuffer(&prvCamera.FileBuffer);
- prvCamera.CaptureWait = 1;
- prvCamera.JPEGEncodeDone = 1;
- prvCamera.CaptureMode = 0;
- Core_EncodeJPEGSetup(NULL, &prvCamera);
- rtos_msg_t msg = {0};
- {
- msg.handler = l_camera_handler;
- msg.ptr = NULL;
- msg.arg1 = 0;
- msg.arg2 = 1;
- luat_msgbus_put(&msg, 1);
- }
- }
- void DecodeQR_CBDataFun(uint8_t *Data, uint32_t Len){
- prvCamera.IsDecoding = 0;
- rtos_msg_t msg = {0};
- if (Data){
- msg.handler = l_camera_handler;
- msg.ptr = Data;
- msg.arg1 = 0;
- msg.arg2 = Len;
- luat_msgbus_put(&msg, 1);
- }
- }
- static int32_t Camera_DrawLcd(void *DrawData, uint8_t Scan){
- LCD_DrawStruct *draw = OS_Malloc(sizeof(LCD_DrawStruct));
- if (!draw){
- DBG("lcd flush no memory");
- return -1;
- }
- uint8_t CPHA = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.CPHA;
- uint8_t CPOL = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.CPOL;
- draw->DCDelay = lcd_conf->dc_delay_us;
- draw->Mode = SPI_MODE_0;
- if(CPHA&&CPOL)draw->Mode = SPI_MODE_3;
- else if(CPOL)draw->Mode = SPI_MODE_2;
- else if(CPHA)draw->Mode = SPI_MODE_1;
- draw->Speed = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.bandrate;
- if (((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->bus_id == 5) draw->SpiID = HSPI_ID0;
- else draw->SpiID = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->bus_id;
- draw->CSPin = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.cs;
- draw->DCPin = lcd_conf->pin_dc;
- draw->xoffset = lcd_conf->xoffset;
- draw->yoffset = lcd_conf->yoffset;
- if (Scan == 0){
- draw->x1 = 0;
- draw->x2 = lcd_conf->w -1;
- draw->y1 = prvCamera.VLen;
- draw->y2 = prvCamera.VLen + prvCamera.drawVLen -1;
- draw->Size = (draw->x2 - draw->x1 + 1) * (draw->y2 - draw->y1 + 1) * 2;
- draw->ColorMode = COLOR_MODE_RGB_565;
- draw->Data = OS_Malloc(draw->Size);
- if (!draw->Data){
- DBG("lcd flush data no memory");
- OS_Free(draw);
- return -1;
- }
- memcpy(draw->Data, DrawData, draw->Size);
- Core_LCDDraw(draw);
- }else if(Scan == 1){
- draw->x1 = 0;
- draw->x2 = prvCamera.Width - 1;
- draw->y1 = 0;
- draw->y2 = prvCamera.Height - 1;
- draw->Size = prvCamera.TotalSize;
- draw->ColorMode = COLOR_MODE_GRAY;
- draw->Data = DrawData;
- Core_CameraDraw(draw);
- }else{
- DBG("Scan error");
- OS_Free(draw);
- return -1;
- }
- }
- static int32_t prvCamera_DCMICB(void *pData, void *pParam){
- uint8_t zbar_scan = (uint8_t)pParam;
- Buffer_Struct *RxBuf = (Buffer_Struct *)pData;
- prvCamera.NewDataFlag = 1;
- if (prvCamera.CaptureMode){
- if (!pData){
- if (prvCamera.CaptureWait && prvCamera.JPEGEncodeDone)
- {
- prvCamera.CaptureWait = 0;
- prvCamera.JPEGEncodeDone = 0;
- Core_EncodeJPEGStart(prvCamera.Width, prvCamera.Height, prvCamera.JPEGQuality);
- }
- else if (!prvCamera.CaptureWait)
- {
- prvCamera.CaptureWait = 1;
- prvCamera.JPEGEncodeDone = 0;
- Core_EncodeJPEGEnd(Camera_SaveJPEGDone, 0);
- }
- }
- else
- {
- if (!prvCamera.CaptureWait)
- {
- uint8_t *data = malloc(RxBuf->MaxLen * 4);
- memcpy(data, RxBuf->Data, RxBuf->MaxLen * 4);
- Core_EncodeJPEGRun(data, RxBuf->MaxLen * 4, zbar_scan?COLOR_MODE_GRAY:COLOR_MODE_RGB_565);
- }
- }
- return 0;
- }
- if (zbar_scan == 0){
- if (!pData){
- prvCamera.VLen = 0;
- return 0;
- }
- if (draw_lcd)
- {
- Camera_DrawLcd(RxBuf->Data, zbar_scan);
- }
- prvCamera.VLen += prvCamera.drawVLen;
- return 0;
- }else if (zbar_scan == 1){
- Buffer_Struct *RxBuf = (Buffer_Struct *)pData;
- if (!pData)
- {
- if (!prvCamera.DataCache && !prvCamera.IsDecoding)
- {
- prvCamera.DataCache = malloc(prvCamera.TotalSize);
- }
- else if (prvCamera.DataCache)
- {
- if (draw_lcd) {
- Camera_DrawLcd(prvCamera.DataCache, zbar_scan);
- }
- Core_DecodeQR(prvCamera.DataCache, prvCamera.Width, prvCamera.Height, DecodeQR_CBDataFun);
- prvCamera.DataCache = NULL;
- prvCamera.IsDecoding = 1;
- }
- prvCamera.CurSize = 0;
- return 0;
- }
- if (prvCamera.DataCache)
- {
- memcpy(&prvCamera.DataCache[prvCamera.CurSize], RxBuf->Data, RxBuf->MaxLen * 4);
- prvCamera.CurSize += RxBuf->MaxLen * 4;
- if (prvCamera.TotalSize < prvCamera.CurSize){
- DBG_ERR("%d,%d", prvCamera.TotalSize, prvCamera.CurSize);
- prvCamera.CurSize = 0;
- }
- }
- return 0;
- }
- }
- int luat_camera_init(luat_camera_conf_t *conf){
-
- int error = ERROR_NONE;
- GPIO_Iomux(GPIOD_01, 3);
- GPIO_Iomux(GPIOD_02, 3);
- GPIO_Iomux(GPIOD_03, 3);
- GPIO_Iomux(GPIOD_08, 3);
- GPIO_Iomux(GPIOD_09, 3);
- GPIO_Iomux(GPIOD_10, 3);
- GPIO_Iomux(GPIOD_11, 3);
- GPIO_Iomux(GPIOE_00, 3);
- GPIO_Iomux(GPIOE_01, 3);
- GPIO_Iomux(GPIOE_02, 3);
- GPIO_Iomux(GPIOE_03, 3);
- if (!prvCamera.CheckTimer)
- {
- prvCamera.CheckTimer = Timer_Create(prvCamera_DataTimeout, NULL, NULL);
- }
- else
- {
- Timer_Stop(prvCamera.CheckTimer);
- }
- memcpy(&camera_conf, conf, sizeof(luat_camera_conf_t));
- lcd_conf = conf->lcd_conf;
- draw_lcd = conf->draw_lcd;
- if (lcd_conf)
- {
- prvCamera.Width = lcd_conf->w;
- prvCamera.Height = lcd_conf->h;
- }
- else
- {
- prvCamera.Width = camera_conf.sensor_width;
- prvCamera.Height = camera_conf.sensor_height;
- draw_lcd = 0;
- }
- if (conf->zbar_scan == 1){
- prvCamera.DataCache = NULL;
- prvCamera.TotalSize = prvCamera.Width * prvCamera.Height;
- prvCamera.DataBytes = 1;
- }
- GPIO_Iomux(GPIOA_05, 2);
- HWTimer_SetPWM(conf->pwm_id, conf->pwm_period, conf->pwm_pulse, 0);
- prvCamera.PWMID = conf->pwm_id;
- luat_i2c_setup(conf->i2c_id,1,NULL);
- for(size_t i = 0; i < conf->init_cmd_size; i++){
- if (luat_i2c_send(conf->i2c_id, conf->i2c_addr, &(conf->init_cmd[i]), 2,1))
- {
- error = -ERROR_OPERATION_FAILED;
- }
- i++;
- }
- prvCamera.I2CID = conf->i2c_id;
- DCMI_Setup(0, 0, 0, 8, 0);
- DCMI_SetCallback(prvCamera_DCMICB, conf->zbar_scan);
- // if (conf->zbar_scan == 0){
- // 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);
- // DCMI_CaptureSwitch(1, 0,lcd_conf->w, lcd_conf->h, 2, &prvCamera.drawVLen);
- // prvCamera.VLen = 0;
- // }else if(conf->zbar_scan == 1){
- // 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);
- // DCMI_CaptureSwitch(1, 0,lcd_conf->w, lcd_conf->h, prvCamera.DataBytes, &prvCamera.drawVLen);
- // }
- return error;
- }
- int luat_camera_start(int id)
- {
- if (prvCamera.DataCache)
- {
- DCMI_CaptureSwitch(0, 0, 0, 0, 0, NULL);
- free(prvCamera.DataCache);
- }
- if (camera_conf.zbar_scan == 0){
- if (lcd_conf)
- {
- 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);
- DCMI_CaptureSwitch(1, 0, lcd_conf->w, lcd_conf->h, 2, &prvCamera.drawVLen);
- }
- else
- {
- DCMI_SetCROPConfig(0, 0, 0, 0, 0);
- DCMI_CaptureSwitch(1, 0, camera_conf.sensor_width, camera_conf.sensor_height, 2, &prvCamera.drawVLen);
- }
- prvCamera.CaptureMode = 0;
- prvCamera.VLen = 0;
- }else if(camera_conf.zbar_scan == 1){
- if (lcd_conf)
- {
- 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);
- DCMI_CaptureSwitch(1, 0,lcd_conf->w, lcd_conf->h, prvCamera.DataBytes, &prvCamera.drawVLen);
- }
- else
- {
- DCMI_SetCROPConfig(0, 0, 0, 0, 0);
- DCMI_CaptureSwitch(1, 0, camera_conf.sensor_width, camera_conf.sensor_height, prvCamera.DataBytes, &prvCamera.drawVLen);
- }
- }
- prvCamera.NewDataFlag = 0;
- Timer_StartMS(prvCamera.CheckTimer, 1000, 1);
- return 0;
- }
- int luat_camera_capture(int id, uint8_t quality, const char *path)
- {
- DCMI_CaptureSwitch(0, 0, 0, 0, 0, NULL);
- if (prvCamera.DataCache)
- {
- free(prvCamera.DataCache);
- prvCamera.DataCache = NULL;
- }
- if (path)
- {
- OS_ReInitBuffer(&prvCamera.JPEGSavePath, strlen(path) + 1);
- memcpy(prvCamera.JPEGSavePath.Data, path, strlen(path));
- }
- OS_ReInitBuffer(&prvCamera.FileBuffer, 16 * 1024);
- Core_EncodeJPEGSetup(Camera_SaveJPEGData, &prvCamera);
- luat_camera_start(id);
- prvCamera.JPEGQuality = quality;
- prvCamera.CaptureMode = 1;
- prvCamera.CaptureWait = 1;
- prvCamera.JPEGEncodeDone = 1;
- Timer_StartMS(prvCamera.CheckTimer, 1000, 1);
- return 0;
- }
- int luat_camera_stop(int id)
- {
- Timer_Stop(prvCamera.CheckTimer);
- DCMI_CaptureSwitch(0, 0, 0, 0, 0, NULL);
- if (prvCamera.DataCache)
- {
- free(prvCamera.DataCache);
- prvCamera.DataCache = NULL;
- }
- OS_DeInitBuffer(&prvCamera.FileBuffer);
- return 0;
- }
- int luat_camera_close(int id)
- {
- luat_camera_stop(id);
- GPIO_Iomux(GPIOD_01, 1);
- GPIO_Iomux(GPIOD_02, 1);
- GPIO_Iomux(GPIOD_03, 1);
- GPIO_Iomux(GPIOD_08, 1);
- GPIO_Iomux(GPIOD_09, 1);
- GPIO_Iomux(GPIOD_10, 1);
- GPIO_Iomux(GPIOD_11, 1);
- GPIO_Iomux(GPIOE_00, 1);
- GPIO_Iomux(GPIOE_01, 1);
- GPIO_Iomux(GPIOE_02, 1);
- GPIO_Iomux(GPIOA_05, 1);
- HWTimer_Stop(prvCamera.PWMID);
- luat_i2c_close(prvCamera.I2CID);
- }
|