/*================================================================ Copyright (c) 2021, Quectel Wireless Solutions Co., Ltd. All rights reserved. Quectel Wireless Solutions Proprietary and Confidential. =================================================================*/ /*================================================================= EDIT HISTORY FOR MODULE This section contains comments describing changes made to the module. Notice that changes are listed in reverse chronological order. WHEN WHO WHAT, WHERE, WHY ------------ ------- ------------------------------------------------------------------------------- =================================================================*/ /*=========================================================================== * include files ===========================================================================*/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include "ql_api_osi.h" #include "ql_log.h" #include "ql_api_camera.h" #include "camera_demo.h" #include "ql_i2c.h" #include "ql_lcd.h" /*=========================================================================== * Macro Definition ===========================================================================*/ #define QL_CAMERADEMO_LOG_LEVEL QL_LOG_LEVEL_INFO #define QL_CAMERADEMO_LOG(msg, ...) QL_LOG(QL_CAMERADEMO_LOG_LEVEL, "ql_CAMERADEMO", msg, ##__VA_ARGS__) #define QL_CAMERADEMO_LOG_PUSH(msg, ...) QL_LOG_PUSH("ql_CAMERADEMO", msg, ##__VA_ARGS__) #define QL_CAMERA_TASK_STACK_SIZE 10240 #define QL_CAMERA_TASK_PRIO APP_PRIORITY_NORMAL #define QL_CAMERA_TASK_EVENT_CNT 5 #define SalveAddr_w (0x42 >> 1) #define SalveAddr_r (0x43 >> 1) #define TEST_CAPTURE_COUNTS (10) #define TEST_PREVIEW_COUNTS (500) /*=========================================================================== * Struct ===========================================================================*/ typedef enum { preview_TEST = 0, //test preview capture_TEST = 1, //test capture }QL_CAM_TEST_E; /*=========================================================================== * Variate ===========================================================================*/ /*=========================================================================== * Functions ===========================================================================*/ void ql_CamUYVY640to320(unsigned char* indata,unsigned char* outBuf) { for(int y = 0; y < 240; y++) { for(int x = 0; x < 320*2; x++) { outBuf[320*2*y+x] = indata[640*2*2*y+x+(x/4)*4]; } } } //if you need to rotate lcd,you could use this api int ql_camPrintExt(uint16_t *imageBuf) { uint16_t *dataBUf = NULL; int offset = 0; //unsigned char* outBuf = NULL; //outBuf = (unsigned char*)malloc(320*240*2);//Space for a display screen ql_lcd_config_t lcd_config = {0}; ql_lcd_get_config(&lcd_config); lcd_config.lcdrotation = 1; lcd_config.widthoriginal = 320; lcd_config.lcdcolorformat = QL_LCD_YUV422_YUYV; lcd_config.clean_screen = false; lcd_config.bus_mode = QL_LCD_SPI_LINE_4; lcd_config.freq = 0; // use default freq if(imageBuf == NULL) { if(ql_CamPreviewDQBUF(&dataBUf) != QL_CAMERA_SUCCESS) { QL_CAMERADEMO_LOG("Cam not preview"); return -1; } //Preview without rotation, use this section lcd_config.lcdrotation = 1; ql_lcd_set_config(&lcd_config); //ql_CamUYVY640to320((unsigned char*)dataBUf,outBuf); offset = 320 * (240 - 1) * 2;//width of camera:320,height of camera:240,byte of a pixel:2 ql_lcd_write((uint16_t *)((uint32_t)dataBUf + offset), 0, 0, 239, 319); ql_CamPreviewQBUF((uint16_t *)dataBUf); //Preview the rotation using this section //lcd_config.lcdrotation = 0; //ql_lcd_set_config(&lcd_config); //ql_lcd_write(dataBUf, 0, 0, 319, 239); //ql_CamPreviewQBUF((uint16_t *)dataBUf); } else { //ATTENTION:If you do not rotate the LCD, please set the LCD to landscape, i.e. 320 x 240 lcd_config.lcdrotation = 0; ql_lcd_set_config(&lcd_config); //ql_CamUYVY640to320((unsigned char*)imageBuf,outBuf); ql_lcd_set_display_offset(0, 0, -80, 80); ql_spi_lcd_write_cmd(0x36); ql_spi_lcd_write_data(0x60); ql_lcd_write((uint16_t *)imageBuf, 0, 0, 319, 239); } //free(outBuf); return 0; } void ql_CamTest(QL_CAM_TEST_E TestMode) { uint16_t *pCamDataBuffer = NULL; uint16_t i; if(TestMode == preview_TEST) { for(i=0;i<TEST_PREVIEW_COUNTS;i++) { ql_camPrint(pCamDataBuffer); //ql_camPrintExt(pCamDataBuffer); //下面延时设置请根据cam的接口(spi\mipi)以及buf配置适当调节 ql_rtos_task_sleep_ms(60); } } else { for(i=0;i<TEST_CAPTURE_COUNTS;i++) { ql_CamCaptureImage(&pCamDataBuffer); ql_camPrint(pCamDataBuffer); //ql_camPrintExt(pCamDataBuffer); ql_rtos_task_sleep_ms(2000); } } } void ql_camera_demo_thread(void *param) { int lcdstatus; //uint8_t read_data = 0; //uint8_t data = 0xaa; ql_CamInit(320, 240); //ql_CamInit(640, 480); //ql_CamInit0310SPI(320, 240); //ql_CamInit0310SPI(640, 480); ql_CamPowerOn(); lcdstatus = ql_lcd_init(); if(lcdstatus == QL_SUCCESS) ql_lcd_display_on(); //The api is used to read the register of sensor,after the camera is successfully powered on. //ql_CamI2CRead(0xf0, &read_data, 1); //The api is used to write the register of sensor,after the camera is successfully powered on. //ql_CamI2CWrite(0x55, data); /*Camera test*/ ql_CamPreview(); ql_CamTest(preview_TEST); ql_CamTest(capture_TEST); ql_CamStopPreview(); ql_CamPowerOff(); ql_rtos_task_sleep_ms(2000); ql_CamPowerOn(); ql_CamPreview(); ql_CamTest(preview_TEST); ql_CamTest(capture_TEST); ql_CamStopPreview(); ql_CamClose(); if(lcdstatus == QL_SUCCESS) ql_lcd_display_off(); ql_rtos_task_delete(NULL); } void ql_camera_app_init(void) { QlCAMERAStatus err = QL_OSI_SUCCESS; ql_task_t camera_task = NULL; err = ql_rtos_task_create(&camera_task, QL_CAMERA_TASK_STACK_SIZE, QL_CAMERA_TASK_PRIO, "camera DEMO", ql_camera_demo_thread, NULL, QL_CAMERA_TASK_EVENT_CNT); if (err != QL_OSI_SUCCESS) { QL_CAMERADEMO_LOG("CAMERA demo task created failed"); } }