sdk-hwV1.3/lichee/xr806/appos/project/common/cmd/cmd_camera.c

306 lines
9.1 KiB
C
Executable File

/*
* Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if ((CONFIG_CHIP_ARCH_VER == 1) || (CONFIG_CHIP_ARCH_VER == 2))
#include "common/cmd/cmd_util.h"
#include "driver/component/csi_camera/camera.h"
#include "cmd_camera.h"
#include "kernel/os/os.h"
#include "driver/chip/hal_i2c.h"
//#define SENSOR_GC0308
#ifdef SENSOR_GC0308
#include "driver/component/csi_camera/gc0308/drv_gc0308.h"
#define SENSOR_FUNC_INIT HAL_GC0308_Init
#define SENSOR_FUNC_DEINIT HAL_GC0308_DeInit
#define SENSOR_FUNC_IOCTL HAL_GC0308_IoCtl
#else
#include "driver/component/csi_camera/gc0328c/drv_gc0328c.h"
#define SENSOR_FUNC_INIT HAL_GC0328C_Init
#define SENSOR_FUNC_DEINIT HAL_GC0328C_DeInit
#define SENSOR_FUNC_IOCTL HAL_GC0328C_IoCtl
#endif
#define CSI_JPEG_PSRAM_EN (1)
#if CSI_JPEG_PSRAM_EN
#include "sys/dma_heap.h"
#define CSI_JPEG_PSRAM_SIZE (520*1024)
#endif
#define CSI_JPEG_MEMPART_EN (0)
#if CSI_JPEG_MEMPART_EN
#define CSI_JPEG_BUFF_SIZE (8*1024)
#else
#define CSI_JPEG_BUFF_SIZE (45*1024)
#endif
#define CSI_JPEG_VIDEO_EN (0)
#define CSI_JPEG_ONLINE_EN (1)
#define CSI_JPEG_SRAM_SIZE (100*1024)
#define IMAGE_SENSOR_I2CID I2C0_ID
#define SENSOR_RESET_PIN GPIO_PIN_15
#define SENSOR_RESET_PORT GPIO_PORT_A
#define SENSOR_POWERDOWN_PIN GPIO_PIN_14
#define SENSOR_POWERDOWN_PORT GPIO_PORT_A
static uint8_t *gmemaddr;
static CAMERA_Mgmt mem_mgmt;
static CAMERA_Cfg camera_cfg = {
.jpeg_cfg.jpeg_en = 1,
.jpeg_cfg.quality = 64,
.jpeg_cfg.jpeg_clk = 0, //no use
.jpeg_cfg.memPartEn = CSI_JPEG_MEMPART_EN,
.jpeg_cfg.memPartNum = CSI_JPEG_MEMPART_EN ? JPEG_MEM_BLOCK4 : 0,
.jpeg_cfg.jpeg_mode = CSI_JPEG_ONLINE_EN ? JPEG_MOD_ONLINE : JPEG_MOD_OFFLINE,
.jpeg_cfg.width = 640,
.jpeg_cfg.height = 480,
.csi_cfg.csi_clk = 24000000, // no use
/* sensor config */
.sensor_cfg.i2c_id = IMAGE_SENSOR_I2CID,
.sensor_cfg.pwcfg.Pwdn_Port = SENSOR_POWERDOWN_PORT,
.sensor_cfg.pwcfg.Reset_Port = SENSOR_RESET_PORT,
.sensor_cfg.pwcfg.Pwdn_Pin = SENSOR_POWERDOWN_PIN,
.sensor_cfg.pwcfg.Reset_Pin = SENSOR_RESET_PIN,
.sensor_func.init = SENSOR_FUNC_INIT,
.sensor_func.deinit = SENSOR_FUNC_DEINIT,
.sensor_func.ioctl = SENSOR_FUNC_IOCTL,
};
static int camera_mem_create(CAMERA_JpegCfg *jpeg_cfg, CAMERA_Mgmt *mgmt)
{
uint8_t *addr;
uint8_t *end_addr;
#if CSI_JPEG_PSRAM_EN
addr = (uint8_t *)dma_malloc(CSI_JPEG_PSRAM_SIZE, DMAHEAP_PSRAM);
if (addr == NULL) {
CMD_SYSLOG("malloc fail\n");
return -1;
}
cmd_memset(addr, 0, CSI_JPEG_PSRAM_SIZE);
end_addr = addr + CSI_JPEG_PSRAM_SIZE;
#else
addr = (uint8_t *)cmd_malloc(CSI_JPEG_SRAM_SIZE);//imgbuf;
if (addr == NULL) {
CMD_SYSLOG("malloc fail\n");
return -1;
}
cmd_memset(addr, 0, CSI_JPEG_SRAM_SIZE);
end_addr = addr + CSI_JPEG_SRAM_SIZE;
#endif
CMD_SYSLOG("malloc addr: %p -> %p\n", addr, end_addr);
mgmt->yuv_buf.addr = (uint8_t *)ALIGN_16B((uint32_t)addr);
mgmt->yuv_buf.size = camera_cfg.jpeg_cfg.width * camera_cfg.jpeg_cfg.height / 2 * 3;
#if CSI_JPEG_ONLINE_EN
mgmt->jpeg_buf[0].addr = (uint8_t *)ALIGN_1K((uint32_t)addr + CAMERA_JPEG_HEADER_LEN);
#if (CSI_JPEG_VIDEO_EN && !CSI_JPEG_MEMPART_EN)
mgmt->jpeg_buf[1].addr = (uint8_t *)ALIGN_1K(
(uint32_t)mgmt->jpeg_buf[0].addr + CSI_JPEG_BUFF_SIZE + CAMERA_JPEG_HEADER_LEN);
mgmt->jpeg_buf[1].size = CSI_JPEG_BUFF_SIZE;
#endif
#else
mgmt->jpeg_buf[0].addr = (uint8_t *)ALIGN_1K(
(uint32_t)mgmt->yuv_buf.addr + CAMERA_JPEG_HEADER_LEN + mgmt->yuv_buf.size);//after yuv data
#endif
mgmt->jpeg_buf[0].size = CSI_JPEG_BUFF_SIZE;
if ((mgmt->yuv_buf.addr + mgmt->yuv_buf.size) > end_addr ||
(mgmt->jpeg_buf[0].addr + mgmt->jpeg_buf[0].size) > end_addr) {
CMD_ERR("aadr exceeded\n");
return -1;
}
gmemaddr = addr;
return 0;
}
static void camera_mem_destroy(void)
{
if (gmemaddr) {
#if CSI_JPEG_PSRAM_EN
dma_free(gmemaddr, DMAHEAP_PSRAM);
#else
cmd_free(gmemaddr);
#endif
gmemaddr = NULL;
}
}
enum cmd_status cmd_camera_init_exec(char *cmd)
{
/* malloc mem */
cmd_memset(&mem_mgmt, 0, sizeof(CAMERA_Mgmt));
if (camera_mem_create(&camera_cfg.jpeg_cfg, &mem_mgmt) != 0)
return CMD_STATUS_FAIL;
/* camera init */
camera_cfg.mgmt = &mem_mgmt;
if (HAL_CAMERA_Init(&camera_cfg) != HAL_OK) {
CMD_ERR("%s init fail\n", cmd);
return CMD_STATUS_FAIL;
}
return CMD_STATUS_OK;
}
enum cmd_status cmd_camera_cap_one_image_exec(char *cmd)
{
int i;
uint8_t *addr;
int size;
CAMERA_JpegBuffInfo jpeg_info;
size = HAL_CAMERA_CaptureImage(CAMERA_OUT_JPEG, &jpeg_info, 1);
if (size < 0) {
CMD_ERR("cap one image failed\n");
return CMD_STATUS_FAIL;
}
CMD_SYSLOG("fm_szie %d\n", jpeg_info.size);
/* jpeg header data*/
addr = mem_mgmt.jpeg_buf[jpeg_info.buff_index].addr - CAMERA_JPEG_HEADER_LEN;
for (i = 0; i < CAMERA_JPEG_HEADER_LEN; i++)
CMD_SYSLOG("%02x ", addr[i]);
/* jpeg body data*/
for (i = 0; i < jpeg_info.size; i++) {
addr = mem_mgmt.jpeg_buf[jpeg_info.buff_index].addr;
CMD_SYSLOG("%02x ", addr[i]);
}
CMD_SYSLOG("\n write jpeg ok\n");
/* yuv420 NV12 data */
if (camera_cfg.jpeg_cfg.jpeg_mode == JPEG_MOD_OFFLINE) {
for (i = 0; i < camera_cfg.jpeg_cfg.width*camera_cfg.jpeg_cfg.height*3/2; i++)
CMD_SYSLOG("%02x ", mem_mgmt.yuv_buf.addr[i]);
CMD_SYSLOG("\n write yuv420 nv12 ok\n");
}
return CMD_STATUS_OK;
}
/* user need quickly take data away, otherwise easy data coverage */
/* need pixel small, the cmd example suppose the data can not bigger
* than 20k, you can set pixel width 160,height 120;
*/
enum cmd_status cmd_camera_cap_video_exec(char *cmd)
{
int i;
uint8_t *tmp_buf[2];
uint32_t tmp_size[2];
CAMERA_JpegBuffInfo jpeg_info;
tmp_buf[0] = (uint8_t *)cmd_malloc(30 * 1024);
if (tmp_buf[0] == NULL) {
CMD_ERR("malloc tmp_buf[0] failed\n");
return CMD_STATUS_FAIL;
}
tmp_buf[1] = (uint8_t *)cmd_malloc(30 * 1024);
if (tmp_buf[1] == NULL) {
CMD_ERR("malloc tmp_buf[1] failed\n");
cmd_free(tmp_buf[0]);
return CMD_STATUS_FAIL;
}
cmd_memset(tmp_buf[0], 0, 30 * 1024);
cmd_memset(tmp_buf[1], 0, 30 * 1024);
if (HAL_CAMERA_CaptureVideoStart() != HAL_OK) {
CMD_ERR("start video failed\n");
cmd_free(tmp_buf[0]);
cmd_free(tmp_buf[1]);
return CMD_STATUS_FAIL;
}
for (i = 0; i < 2; i++) { /* for example, 2 frame continue */
int ret = HAL_CAMERA_CaptureVideoData(&jpeg_info);
CMD_SYSLOG("frame index=%d size=%d\n", jpeg_info.buff_index, jpeg_info.size);
if (ret != 0) {
CMD_ERR("cap video image failed\n");
cmd_free(tmp_buf[0]);
cmd_free(tmp_buf[1]);
return CMD_STATUS_FAIL;
}
tmp_size[i] = jpeg_info.size + CAMERA_JPEG_HEADER_LEN;
cmd_memcpy(tmp_buf[i],
mem_mgmt.jpeg_buf[jpeg_info.buff_index].addr - CAMERA_JPEG_HEADER_LEN,
jpeg_info.size + CAMERA_JPEG_HEADER_LEN);
}
HAL_CAMERA_CaptureVideoStop();
for (i = 0; i < tmp_size[0]; i++) { /* first frame */
CMD_SYSLOG("%02x ", *(tmp_buf[0] + i));
}
CMD_SYSLOG("\nwrite jpeg ok\n");
for (i = 0; i < tmp_size[1]; i++) { /* sencond frame */
CMD_SYSLOG("%02x ", *(tmp_buf[1] + i));
}
CMD_SYSLOG("\nwrite jpeg ok\n");
cmd_free(tmp_buf[0]);
cmd_free(tmp_buf[1]);
return CMD_STATUS_OK;
}
enum cmd_status cmd_camera_deinit_exec(char *cmd)
{
HAL_CAMERA_DeInit();
camera_mem_destroy();
return CMD_STATUS_OK;
}
static const struct cmd_data g_camera_cmds[] = {
{ "init", cmd_camera_init_exec},
{ "cap_one_image", cmd_camera_cap_one_image_exec},
{ "cap_video_image", cmd_camera_cap_video_exec},
{ "deinit", cmd_camera_deinit_exec},
};
enum cmd_status cmd_camera_exec(char *cmd)
{
return cmd_exec(cmd, g_camera_cmds, cmd_nitems(g_camera_cmds));
}
#endif