openmv/lib/alif/drivers/source/cpi.c
iabdalkader daf2bb30da misc: Restructure repo.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
2025-04-13 08:28:34 +02:00

116 lines
4.3 KiB
C

/* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved.
* Use, distribution and modification of this code is permitted under the
* terms stated in the Alif Semiconductor Software License Agreement
*
* You should have received a copy of the Alif Semiconductor Software
* License Agreement with this file. If not, please write to:
* contact@alifsemi.com, or visit: https://alifsemi.com/license
*
*/
/**************************************************************************//**
* @file cpi.c
* @author Chandra Bhushan Singh
* @email chandrabhushan.singh@alifsemi.com
* @version V1.0.0
* @date 27-March-2023
* @brief Low level driver Specific source file.
******************************************************************************/
#include "cpi.h"
/**
\fn void cpi_software_reset(CPI_Type *cpi)
\brief CPI software reset
\param[in] cpi Pointer to the CPI register map.
\param[in] mode Soft reset the CPI
\return none.
*/
void cpi_software_reset(CPI_Type *cpi)
{
cpi->CAM_CTRL = 0;
cpi->CAM_CTRL |= CAM_CTRL_SW_RESET;
cpi->CAM_CTRL = 0;
cpi->CAM_CTRL = (CAM_CTRL_START | CAM_CTRL_FIFO_CLK_SEL);
}
/**
\fn void cpi_start_capture(CPI_Type *cpi, CPI_MODE_SELECT mode)
\brief Capture frame in snapshot/ continuous capture mode.
-Set CAM_CTRL = 0—prepare for soft reset
-Set CAM_CTRL = 0x100—activate soft reset
-Set CAM_CTRL = 0—stop soft reset
-Set CAM_CTRL = 0x1001 or 0x1011—start the CPI controller,
with bit [SNAPSHOT] defining the operation mode:
-[SNAPSHOT] = 0—Capture video frames continuously
-[SNAPSHOT] = 1—Capture one frame then stop
\param[in] cpi Pointer to the CPI register map.
\param[in] mode Select to capture one frame and stop/ or to capture video frames continuously
\return none.
*/
void cpi_start_capture(CPI_Type *cpi, CPI_MODE_SELECT mode)
{
cpi->CAM_CTRL = 0;
cpi->CAM_CTRL |= CAM_CTRL_SW_RESET;
cpi->CAM_CTRL = 0;
if(mode == CPI_MODE_SELECT_SNAPSHOT)
{
cpi->CAM_CTRL = (CAM_CTRL_SNAPSHOT | CAM_CTRL_START | CAM_CTRL_FIFO_CLK_SEL);
}
else
{
cpi->CAM_CTRL = (CAM_CTRL_START | CAM_CTRL_FIFO_CLK_SEL);
}
}
/**
\fn void cpi_set_config(CPI_Type *cpi, cpi_cfg_info_t *info)
\brief Configure the cpi with given information.
\param[in] cpi Pointer to CPI register map
\param[in] info Pointer to cpi configuration structure.
\return none
*/
void cpi_set_config(CPI_Type *cpi, cpi_cfg_info_t *info)
{
cpi->CAM_CFG = (info->sensor_info.interface | (info->sensor_info.vsync_wait << CAM_CFG_VSYNC_WAIT_Pos) |
(info->sensor_info.vsync_mode << CAM_CFG_VSYNC_MODE_Pos) |
(info->rw_roundup << CAM_CFG_ROW_ROUNDUP_Pos) |
(info->sensor_info.pixelclk_pol << CAM_CFG_PIXELCLK_POL_Pos) |
(info->sensor_info.hsync_pol << CAM_CFG_HSYNC_POL_Pos) |
(info->sensor_info.vsync_pol << CAM_CFG_VSYNC_POL_Pos) |
(info->sensor_info.data_mode << CAM_CFG_DATA_MODE_Pos));
if(info->sensor_info.data_mode <= CPI_DATA_MODE_BIT_8)
{
cpi->CAM_CFG |= (info->sensor_info.data_endianness << CAM_CFG_DATA_ENDIANNESS_Pos);
}
if(info->sensor_info.data_mode == CPI_DATA_MODE_BIT_8)
{
cpi->CAM_CFG |= (info->sensor_info.code10on8 << CAM_CFG_CODE10ON8_Pos);
}
if(info->sensor_info.data_mode == CPI_DATA_MODE_BIT_16)
{
cpi->CAM_CFG &= ~CAM_CFG_DATA_MASK_Msk;
cpi->CAM_CFG |= (info->sensor_info.data_mask << CAM_CFG_DATA_MASK_Pos);
}
cpi->CAM_FIFO_CTRL &= ~CAM_FIFO_CTRL_RD_WMARK_Msk;
cpi->CAM_FIFO_CTRL = info->fifo_ctrl.rd_wmark;
cpi->CAM_FIFO_CTRL &= ~CAM_FIFO_CTRL_WR_WMARK_Msk;
cpi->CAM_FIFO_CTRL |= (info->fifo_ctrl.wr_wmark << CAM_FIFO_CTRL_WR_WMARK_Pos);
cpi->CAM_VIDEO_FCFG &= ~CAM_VIDEO_FCFG_DATA_Msk;
cpi->CAM_VIDEO_FCFG = info->frame_cfg.data;
cpi->CAM_VIDEO_FCFG &= ~CAM_VIDEO_FCFG_ROW_Msk;
cpi->CAM_VIDEO_FCFG |= (info->frame_cfg.row << CAM_VIDEO_FCFG_ROW_Pos);
if(info->sensor_info.interface == CPI_INTERFACE_MIPI_CSI)
{
cpi->CAM_CSI_CMCFG |= info->csi_ipi_color_mode;
}
}