[add] dcmi and ov2640 driver.
This commit is contained in:
parent
9dc0bbb814
commit
2fa563f164
|
@ -41,6 +41,13 @@ menu "Onboard Peripheral Drivers"
|
||||||
select RT_USING_DFS_ELMFAT
|
select RT_USING_DFS_ELMFAT
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config BSP_USING_OV2640
|
||||||
|
bool "Enable camera (ov2640)"
|
||||||
|
select BSP_USING_DCMI
|
||||||
|
select BSP_USING_I2C
|
||||||
|
select BSP_USING_I2C2
|
||||||
|
default n
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "On-chip Peripheral Drivers"
|
menu "On-chip Peripheral Drivers"
|
||||||
|
@ -98,28 +105,55 @@ menu "On-chip Peripheral Drivers"
|
||||||
select RT_USING_SPI
|
select RT_USING_SPI
|
||||||
default n
|
default n
|
||||||
|
|
||||||
menuconfig BSP_USING_I2C1
|
menuconfig BSP_USING_I2C
|
||||||
bool "Enable I2C1 BUS (software simulation)"
|
bool "Enable I2C BUS (software simulation)"
|
||||||
default n
|
select RT_USING_I2C
|
||||||
select RT_USING_I2C
|
select RT_USING_I2C_BITOPS
|
||||||
select RT_USING_I2C_BITOPS
|
select RT_USING_PIN
|
||||||
select RT_USING_PIN
|
default n
|
||||||
if BSP_USING_I2C1
|
if BSP_USING_I2C
|
||||||
comment "Notice: PH4 --> 116; PH5 --> 117"
|
menuconfig BSP_USING_I2C1
|
||||||
config BSP_I2C1_SCL_PIN
|
bool "Enable I2C1 BUS (software simulation)"
|
||||||
int "i2c1 scl pin number"
|
default n
|
||||||
range 1 176
|
if BSP_USING_I2C1
|
||||||
default 116
|
comment "Notice: PH4 --> 116; PH5 --> 117"
|
||||||
config BSP_I2C1_SDA_PIN
|
config BSP_I2C1_SCL_PIN
|
||||||
int "I2C1 sda pin number"
|
int "i2c1 scl pin number"
|
||||||
range 1 176
|
range 1 176
|
||||||
default 117
|
default 116
|
||||||
endif
|
config BSP_I2C1_SDA_PIN
|
||||||
|
int "I2C1 sda pin number"
|
||||||
|
range 1 176
|
||||||
|
default 117
|
||||||
|
menuconfig BSP_USING_I2C2
|
||||||
|
bool "Enable I2C2 BUS (software simulation)"
|
||||||
|
default n
|
||||||
|
endif
|
||||||
|
|
||||||
|
menuconfig BSP_USING_I2C2
|
||||||
|
bool "Enable I2C2 BUS (software simulation)"
|
||||||
|
default n
|
||||||
|
if BSP_USING_I2C2
|
||||||
|
comment "Notice: PH13 --> 125; PH15 --> 127"
|
||||||
|
config BSP_I2C2_SCL_PIN
|
||||||
|
int "i2c2 scl pin number"
|
||||||
|
range 1 176
|
||||||
|
default 127
|
||||||
|
config BSP_I2C2_SDA_PIN
|
||||||
|
int "I2C2 sda pin number"
|
||||||
|
range 1 176
|
||||||
|
default 125
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
config BSP_USING_ON_CHIP_FLASH
|
config BSP_USING_ON_CHIP_FLASH
|
||||||
bool "Enable on-chip FLASH"
|
bool "Enable on-chip FLASH"
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config BSP_USING_DCMI
|
||||||
|
bool "Enable DCMI"
|
||||||
|
default n
|
||||||
|
|
||||||
menuconfig BSP_USING_ONCHIP_RTC
|
menuconfig BSP_USING_ONCHIP_RTC
|
||||||
bool "Enable RTC"
|
bool "Enable RTC"
|
||||||
select RT_USING_RTC
|
select RT_USING_RTC
|
||||||
|
|
|
@ -17,6 +17,10 @@ if GetDepend(['BSP_USING_QSPI_FLASH']):
|
||||||
src += Glob('ports/drv_qspi_flash.c')
|
src += Glob('ports/drv_qspi_flash.c')
|
||||||
if GetDepend(['BSP_USING_SDMMC']):
|
if GetDepend(['BSP_USING_SDMMC']):
|
||||||
src += Glob('ports/drv_sdio.c')
|
src += Glob('ports/drv_sdio.c')
|
||||||
|
if GetDepend(['BSP_USING_DCMI']):
|
||||||
|
src += Glob('ports/drv_dcmi.c')
|
||||||
|
if GetDepend(['BSP_USING_OV2640']):
|
||||||
|
src += Glob('ports/drv_ov2640.c')
|
||||||
|
|
||||||
path = [cwd]
|
path = [cwd]
|
||||||
path += [cwd + '/CubeMX_Config/Inc']
|
path += [cwd + '/CubeMX_Config/Inc']
|
||||||
|
|
|
@ -0,0 +1,223 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2020-07-27 thread-liu the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
#if defined(BSP_USING_DCMI)
|
||||||
|
|
||||||
|
#include <drv_dcmi.h>
|
||||||
|
|
||||||
|
#define DRV_DEBUG
|
||||||
|
#define LOG_TAG "drv.dcmi"
|
||||||
|
#include <drv_log.h>
|
||||||
|
|
||||||
|
struct stm32_dcmi
|
||||||
|
{
|
||||||
|
DCMI_HandleTypeDef DCMI_Handle;
|
||||||
|
struct rt_dcmi_device dev;
|
||||||
|
};
|
||||||
|
static struct stm32_dcmi rt_dcmi = {0};
|
||||||
|
|
||||||
|
DMA_HandleTypeDef hdma_dcmi;
|
||||||
|
|
||||||
|
static void rt_hw_dcmi_dma_init(void)
|
||||||
|
{
|
||||||
|
__HAL_RCC_DMA2_CLK_ENABLE();
|
||||||
|
|
||||||
|
hdma_dcmi.Instance = DMA2_Stream1;
|
||||||
|
hdma_dcmi.Init.Request = DMA_REQUEST_DCMI;
|
||||||
|
hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||||
|
hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||||
|
hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
|
||||||
|
hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
|
||||||
|
hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
|
||||||
|
hdma_dcmi.Init.Mode = DMA_CIRCULAR;
|
||||||
|
hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH;
|
||||||
|
hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
|
||||||
|
hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||||
|
hdma_dcmi.Init.MemBurst = DMA_MBURST_SINGLE;
|
||||||
|
hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;
|
||||||
|
|
||||||
|
HAL_DMA_DeInit(&hdma_dcmi);
|
||||||
|
HAL_DMA_Init(&hdma_dcmi);
|
||||||
|
|
||||||
|
__HAL_LINKDMA(&rt_dcmi.DCMI_Handle, DMA_Handle, hdma_dcmi);
|
||||||
|
|
||||||
|
HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0x00, 0x00);
|
||||||
|
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint32_t len)
|
||||||
|
{
|
||||||
|
__HAL_UNLOCK(&hdma_dcmi);
|
||||||
|
|
||||||
|
HAL_DMAEx_MultiBufferStart(&hdma_dcmi, (rt_uint32_t)&DCMI->DR, dst_addr1, dst_addr2, len);
|
||||||
|
|
||||||
|
__HAL_DMA_ENABLE_IT(&hdma_dcmi, DMA_IT_TC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_hw_dcmi_init(DCMI_HandleTypeDef *device)
|
||||||
|
{
|
||||||
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
device->Instance = DCMI;
|
||||||
|
device->Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
|
||||||
|
device->Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
|
||||||
|
device->Init.VSPolarity = DCMI_VSPOLARITY_LOW;
|
||||||
|
device->Init.HSPolarity = DCMI_HSPOLARITY_LOW;
|
||||||
|
device->Init.CaptureRate = DCMI_CR_ALL_FRAME;
|
||||||
|
device->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
|
||||||
|
device->Init.JPEGMode = DCMI_JPEG_ENABLE;
|
||||||
|
device->Init.ByteSelectMode = DCMI_BSM_ALL;
|
||||||
|
device->Init.ByteSelectStart = DCMI_OEBS_ODD;
|
||||||
|
device->Init.LineSelectMode = DCMI_LSM_ALL;
|
||||||
|
device->Init.LineSelectStart = DCMI_OELS_ODD;
|
||||||
|
|
||||||
|
if (HAL_DCMI_Init(device) != HAL_OK)
|
||||||
|
{
|
||||||
|
LOG_E("dcmi init error!");
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
DCMI->IER = 0x0;
|
||||||
|
|
||||||
|
__HAL_DCMI_ENABLE_IT(device, DCMI_IT_FRAME);
|
||||||
|
__HAL_DCMI_ENABLE(device);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DCMI_IRQHandler(void)
|
||||||
|
{
|
||||||
|
/* enter interrupt */
|
||||||
|
rt_interrupt_enter();
|
||||||
|
|
||||||
|
HAL_DCMI_IRQHandler(&rt_dcmi.DCMI_Handle);
|
||||||
|
|
||||||
|
/* leave interrupt */
|
||||||
|
rt_interrupt_leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DCMI_Start(void)
|
||||||
|
{
|
||||||
|
__HAL_DMA_ENABLE(&hdma_dcmi);
|
||||||
|
DCMI->CR |= DCMI_CR_CAPTURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DCMI_Stop(void)
|
||||||
|
{
|
||||||
|
DCMI->CR &= ~(DCMI_CR_CAPTURE);
|
||||||
|
while (DCMI->CR & 0x01);
|
||||||
|
__HAL_DMA_DISABLE(&hdma_dcmi);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Capture a frame of the image */
|
||||||
|
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
|
||||||
|
{
|
||||||
|
extern void camera_frame_data_process(void);
|
||||||
|
/* enter interrupt */
|
||||||
|
rt_interrupt_enter();
|
||||||
|
/* move frame data to buffer */
|
||||||
|
camera_frame_data_process();
|
||||||
|
|
||||||
|
__HAL_DCMI_ENABLE_IT(&rt_dcmi.DCMI_Handle, DCMI_IT_FRAME);
|
||||||
|
|
||||||
|
/* leave interrupt */
|
||||||
|
rt_interrupt_leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DMA2_Stream1_IRQHandler(void)
|
||||||
|
{
|
||||||
|
extern void camera_dma_data_process(void);
|
||||||
|
/* enter interrupt */
|
||||||
|
rt_interrupt_enter();
|
||||||
|
|
||||||
|
if (__HAL_DMA_GET_FLAG(&hdma_dcmi, DMA_FLAG_TCIF1_5) != RESET)
|
||||||
|
{
|
||||||
|
__HAL_DMA_CLEAR_FLAG(&hdma_dcmi, DMA_FLAG_TCIF1_5);
|
||||||
|
/* move dma data to buffer */
|
||||||
|
camera_dma_data_process();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* leave interrupt */
|
||||||
|
rt_interrupt_leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_dcmi_init(rt_device_t dev)
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
rt_err_t result = RT_EOK;
|
||||||
|
|
||||||
|
result = rt_hw_dcmi_init(&rt_dcmi.DCMI_Handle);
|
||||||
|
if (result != RT_EOK)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_hw_dcmi_dma_init();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_dcmi_open(rt_device_t dev, rt_uint16_t oflag)
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_dcmi_close(rt_device_t dev)
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_dcmi_control(rt_device_t dev, int cmd, void *args)
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_size_t rt_dcmi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_size_t rt_dcmi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dcmi_init(void)
|
||||||
|
{
|
||||||
|
rt_dcmi.dev.parent.type = RT_Device_Class_Miscellaneous;
|
||||||
|
rt_dcmi.dev.parent.init = rt_dcmi_init;
|
||||||
|
rt_dcmi.dev.parent.open = rt_dcmi_open;
|
||||||
|
rt_dcmi.dev.parent.close = rt_dcmi_close;
|
||||||
|
rt_dcmi.dev.parent.read = rt_dcmi_read;
|
||||||
|
rt_dcmi.dev.parent.write = rt_dcmi_write;
|
||||||
|
rt_dcmi.dev.parent.control = rt_dcmi_control;
|
||||||
|
rt_dcmi.dev.parent.user_data = RT_NULL;
|
||||||
|
|
||||||
|
rt_device_register(&rt_dcmi.dev.parent, "dcmi", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
|
||||||
|
|
||||||
|
LOG_I("dcmi init success!");
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
INIT_BOARD_EXPORT(dcmi_init);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2020-07-27 thread-liu the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DRV_DCMI_H__
|
||||||
|
#define __DRV_DCMI_H__
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct rt_dcmi_device
|
||||||
|
{
|
||||||
|
struct rt_device parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern DMA_HandleTypeDef hdma_dcmi;
|
||||||
|
extern void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint32_t len);
|
||||||
|
extern void DCMI_Start(void);
|
||||||
|
extern void DCMI_Stop(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,751 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2020-08-03 thread-liu the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
#if defined(BSP_USING_OV2640)
|
||||||
|
|
||||||
|
#include <dfs_posix.h>
|
||||||
|
#include <drv_ov2640.h>
|
||||||
|
#include <drv_dcmi.h>
|
||||||
|
#include "pcf8574.h"
|
||||||
|
|
||||||
|
#define DRV_DEBUG
|
||||||
|
//#define CAMERA_DUMP
|
||||||
|
#define LOG_TAG "drv.ov2640"
|
||||||
|
#include <drv_log.h>
|
||||||
|
|
||||||
|
#define DEV_ADDRESS 0x30 /* OV2640 address */
|
||||||
|
#define I2C_NAME "i2c2"
|
||||||
|
|
||||||
|
#define RESET_PIN GET_PIN(A, 15) /* camera reset pin */
|
||||||
|
|
||||||
|
/* camera PWDN pin */
|
||||||
|
#define DCMI_PWDN_IO 2 /* pcf8574 (0-7) */
|
||||||
|
|
||||||
|
volatile rt_uint32_t jpeg_data_len = 0;
|
||||||
|
volatile rt_uint8_t jpeg_data_ok = 0;
|
||||||
|
struct rt_i2c_bus_device *i2c_bus = RT_NULL;
|
||||||
|
|
||||||
|
#define JPEG_BUF_SIZE 32 * 1024
|
||||||
|
#define JPEG_LINE_SIZE 1 * 1024
|
||||||
|
|
||||||
|
static pcf8574_device_t pcf_dev = RT_NULL;
|
||||||
|
|
||||||
|
static rt_uint32_t *jpeg_data_buf = RT_NULL;
|
||||||
|
static rt_uint32_t JPEG_LINE0_BUF[JPEG_LINE_SIZE];
|
||||||
|
static rt_uint32_t JPEG_LINE1_BUF[JPEG_LINE_SIZE];
|
||||||
|
|
||||||
|
#if defined(CAMERA_DUMP)
|
||||||
|
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
|
||||||
|
static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
|
||||||
|
{
|
||||||
|
unsigned char *buf = (unsigned char *)ptr;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < buflen; i += 16)
|
||||||
|
{
|
||||||
|
rt_kprintf("%08x:", i);
|
||||||
|
|
||||||
|
for (j = 0; j < 16; j++)
|
||||||
|
{
|
||||||
|
if (i + j < buflen)
|
||||||
|
{
|
||||||
|
rt_kprintf("%02x", buf[i + j]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rt_kprintf(" ");
|
||||||
|
|
||||||
|
for (j = 0; j < 16; j++)
|
||||||
|
{
|
||||||
|
if (i + j < buflen)
|
||||||
|
{
|
||||||
|
rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rt_kprintf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t len, rt_uint8_t *buf)
|
||||||
|
{
|
||||||
|
struct rt_i2c_msg msg[2];
|
||||||
|
|
||||||
|
RT_ASSERT(bus != RT_NULL);
|
||||||
|
|
||||||
|
msg[0].addr = DEV_ADDRESS;
|
||||||
|
msg[0].flags = RT_I2C_WR;
|
||||||
|
msg[0].buf = ®
|
||||||
|
msg[0].len = 2;
|
||||||
|
|
||||||
|
msg[1].addr = DEV_ADDRESS;
|
||||||
|
msg[1].flags = RT_I2C_RD;
|
||||||
|
msg[1].len = len;
|
||||||
|
msg[1].buf = buf;
|
||||||
|
|
||||||
|
if (rt_i2c_transfer(bus, msg, 2) == 2)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* i2c write reg */
|
||||||
|
static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t data)
|
||||||
|
{
|
||||||
|
rt_uint8_t buf[2];
|
||||||
|
struct rt_i2c_msg msgs;
|
||||||
|
|
||||||
|
RT_ASSERT(bus != RT_NULL);
|
||||||
|
|
||||||
|
buf[0] = reg ;
|
||||||
|
buf[1] = data;
|
||||||
|
|
||||||
|
msgs.addr = DEV_ADDRESS;
|
||||||
|
msgs.flags = RT_I2C_WR;
|
||||||
|
msgs.buf = buf;
|
||||||
|
msgs.len = 2;
|
||||||
|
|
||||||
|
if (rt_i2c_transfer(bus, &msgs, 1) == 1)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t ov2640_read_id(struct rt_i2c_bus_device *bus)
|
||||||
|
{
|
||||||
|
rt_uint8_t read_value[2];
|
||||||
|
rt_uint16_t id = 0;
|
||||||
|
read_reg(bus, OV2640_SENSOR_MIDH, 1, &read_value[0]);
|
||||||
|
read_reg(bus, OV2640_SENSOR_MIDL, 1, &read_value[1]);
|
||||||
|
id = ((rt_uint16_t)(read_value[0] << 8) & 0xFF00);
|
||||||
|
id |= ((rt_uint16_t)(read_value[1]) & 0x00FF);
|
||||||
|
|
||||||
|
if (id != OV2640_MID)
|
||||||
|
{
|
||||||
|
LOG_E("ov2640 init error, mid: 0x%04x", id);
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_I("ov2640 read mid success, mid: 0x%04x", id);
|
||||||
|
|
||||||
|
read_reg(bus, OV2640_SENSOR_PIDH, 1, &read_value[0]);
|
||||||
|
read_reg(bus, OV2640_SENSOR_PIDL, 1, &read_value[1]);
|
||||||
|
id = ((rt_uint16_t)(read_value[0] << 8) & 0xFF00);
|
||||||
|
id |= ((rt_uint16_t)(read_value[1]) & 0x00FF);
|
||||||
|
|
||||||
|
if (id != OV2640_PID)
|
||||||
|
{
|
||||||
|
LOG_E("ov2640 init error, pid: 0x%04x", id);
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_I("ov2640 read hid success, pid: 0x%04x", id);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* change ov2640 to jpeg mode */
|
||||||
|
void ov2640_jpeg_mode(void)
|
||||||
|
{
|
||||||
|
rt_uint16_t i=0;
|
||||||
|
/* set yun422 mode */
|
||||||
|
for (i = 0; i < (sizeof(ov2640_yuv422_reg_tbl) / 2); i++)
|
||||||
|
{
|
||||||
|
write_reg(i2c_bus, ov2640_yuv422_reg_tbl[i][0],ov2640_yuv422_reg_tbl[i][1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set jpeg mode */
|
||||||
|
for(i=0;i<(sizeof(ov2640_jpeg_reg_tbl)/2);i++)
|
||||||
|
{
|
||||||
|
write_reg(i2c_bus, ov2640_jpeg_reg_tbl[i][0],ov2640_jpeg_reg_tbl[i][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* change ov2640 to rgb565 mode */
|
||||||
|
void ov2640_rgb565_mode(void)
|
||||||
|
{
|
||||||
|
rt_uint16_t i=0;
|
||||||
|
for (i = 0; i < (sizeof(ov2640_rgb565_reg_tbl) / 2); i++)
|
||||||
|
{
|
||||||
|
write_reg(i2c_bus, ov2640_rgb565_reg_tbl[i][0],ov2640_rgb565_reg_tbl[i][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set auto exposure */
|
||||||
|
void ov2640_set_auto_exposure(rt_uint8_t level)
|
||||||
|
{
|
||||||
|
rt_uint8_t i = 0;
|
||||||
|
rt_uint8_t *p = (rt_uint8_t*)OV2640_AUTOEXPOSURE_LEVEL[level];
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
write_reg(i2c_bus, p[i*2],p[i*2+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set light mode
|
||||||
|
* 0: auto
|
||||||
|
* 1: sunny
|
||||||
|
* 2: cloudy
|
||||||
|
* 3: office
|
||||||
|
* 4: home
|
||||||
|
* */
|
||||||
|
void ov2640_set_light_mode(rt_uint8_t mode)
|
||||||
|
{
|
||||||
|
rt_uint8_t regccval, regcdval, regceval;
|
||||||
|
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
write_reg(i2c_bus, 0xFF, 0x00);
|
||||||
|
write_reg(i2c_bus, 0xC7, 0x10);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
regccval = 0x65;
|
||||||
|
regcdval = 0x41;
|
||||||
|
regceval = 0x4F;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
regccval = 0x52;
|
||||||
|
regcdval = 0x41;
|
||||||
|
regceval = 0x66;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
regccval = 0x42;
|
||||||
|
regcdval = 0x3F;
|
||||||
|
regceval = 0x71;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
regccval = 0x5E;
|
||||||
|
regcdval = 0x41;
|
||||||
|
regceval = 0x54;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_reg(i2c_bus, 0xFF, 0x00);
|
||||||
|
write_reg(i2c_bus, 0xC7, 0x40);
|
||||||
|
write_reg(i2c_bus, 0xCC, regccval);
|
||||||
|
write_reg(i2c_bus, 0xCD, regcdval);
|
||||||
|
write_reg(i2c_bus, 0xCE, regceval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set color saturation
|
||||||
|
* 0: -2
|
||||||
|
* 1: -1
|
||||||
|
* 2: 0
|
||||||
|
* 3: +1
|
||||||
|
* 4: +2
|
||||||
|
* */
|
||||||
|
void ov2640_set_color_saturation(rt_uint8_t sat)
|
||||||
|
{
|
||||||
|
rt_uint8_t reg7dval = ((sat+2)<<4) | 0x08;
|
||||||
|
write_reg(i2c_bus, 0xFF, 0X00);
|
||||||
|
write_reg(i2c_bus, 0x7C, 0X00);
|
||||||
|
write_reg(i2c_bus, 0x7D, 0X02);
|
||||||
|
write_reg(i2c_bus, 0x7C, 0X03);
|
||||||
|
write_reg(i2c_bus, 0x7D, reg7dval);
|
||||||
|
write_reg(i2c_bus, 0x7D, reg7dval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set brightness
|
||||||
|
* 0: -2
|
||||||
|
* 1: -1
|
||||||
|
* 2: 0
|
||||||
|
* 3: 1
|
||||||
|
* 4: 2
|
||||||
|
* */
|
||||||
|
void ov2640_set_brightness(rt_uint8_t bright)
|
||||||
|
{
|
||||||
|
write_reg(i2c_bus, 0xff, 0x00);
|
||||||
|
write_reg(i2c_bus, 0x7c, 0x00);
|
||||||
|
write_reg(i2c_bus, 0x7d, 0x04);
|
||||||
|
write_reg(i2c_bus, 0x7c, 0x09);
|
||||||
|
write_reg(i2c_bus, 0x7d, bright << 4);
|
||||||
|
write_reg(i2c_bus, 0x7d, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set contrast
|
||||||
|
* 0: -2
|
||||||
|
* 1: -1
|
||||||
|
* 2: 0
|
||||||
|
* 3: 1
|
||||||
|
* 4: 2
|
||||||
|
* */
|
||||||
|
void ov2640_set_contrast(rt_uint8_t contrast)
|
||||||
|
{
|
||||||
|
rt_uint8_t reg7d0val, reg7d1val;
|
||||||
|
|
||||||
|
switch(contrast)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
reg7d0val = 0x18;
|
||||||
|
reg7d1val = 0x34;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
reg7d0val = 0x1C;
|
||||||
|
reg7d1val = 0x2A;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
reg7d0val = 0x24;
|
||||||
|
reg7d1val = 0x16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
reg7d0val = 0x28;
|
||||||
|
reg7d1val = 0x0C;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
reg7d0val = 0x20;
|
||||||
|
reg7d1val = 0x20;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
write_reg(i2c_bus, 0xff, 0x00);
|
||||||
|
write_reg(i2c_bus, 0x7c, 0x00);
|
||||||
|
write_reg(i2c_bus, 0x7d, 0x04);
|
||||||
|
write_reg(i2c_bus, 0x7c, 0x07);
|
||||||
|
write_reg(i2c_bus, 0x7d, 0x20);
|
||||||
|
write_reg(i2c_bus, 0x7d, reg7d0val);
|
||||||
|
write_reg(i2c_bus, 0x7d, reg7d1val);
|
||||||
|
write_reg(i2c_bus, 0x7d, 0x06);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set special effects
|
||||||
|
* 0: noraml
|
||||||
|
* 1: negative film
|
||||||
|
* 2: black-and-white
|
||||||
|
* 3: the red
|
||||||
|
* 4: the green
|
||||||
|
* 5: the blue
|
||||||
|
* 6: Retro
|
||||||
|
*/
|
||||||
|
void ov2640_set_special_effects(rt_uint8_t eft)
|
||||||
|
{
|
||||||
|
rt_uint8_t reg7d0val, reg7d1val, reg7d2val;
|
||||||
|
|
||||||
|
switch(eft)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
reg7d0val = 0x40;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
reg7d0val = 0x18;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
reg7d0val = 0x18;
|
||||||
|
reg7d1val = 0x40;
|
||||||
|
reg7d2val = 0xC0;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
reg7d0val = 0x18;
|
||||||
|
reg7d1val = 0x40;
|
||||||
|
reg7d2val = 0x40;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
reg7d0val = 0x18;
|
||||||
|
reg7d1val = 0xA0;
|
||||||
|
reg7d2val = 0x40;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
reg7d0val = 0x18;
|
||||||
|
reg7d1val = 0x40;
|
||||||
|
reg7d2val = 0xA6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reg7d0val = 0x00;
|
||||||
|
reg7d1val = 0x80;
|
||||||
|
reg7d2val = 0x80;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
write_reg(i2c_bus, 0xff, 0x00);
|
||||||
|
write_reg(i2c_bus, 0x7c, 0x00);
|
||||||
|
write_reg(i2c_bus, 0x7d, reg7d0val);
|
||||||
|
write_reg(i2c_bus, 0x7c, 0x05);
|
||||||
|
write_reg(i2c_bus, 0x7d, reg7d1val);
|
||||||
|
write_reg(i2c_bus, 0x7d, reg7d2val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the image output window */
|
||||||
|
void ov2640_set_window_size(rt_uint16_t sx,rt_uint16_t sy,rt_uint16_t width,rt_uint16_t height)
|
||||||
|
{
|
||||||
|
rt_uint16_t endx;
|
||||||
|
rt_uint16_t endy;
|
||||||
|
rt_uint8_t temp;
|
||||||
|
endx = sx + width / 2;
|
||||||
|
endy = sy + height / 2;
|
||||||
|
|
||||||
|
write_reg(i2c_bus, 0xFF, 0x01);
|
||||||
|
read_reg(i2c_bus, 0x03, 1, &temp);
|
||||||
|
temp &= 0xF0;
|
||||||
|
temp |= ((endy & 0x03) << 2) | (sy & 0x03);
|
||||||
|
write_reg(i2c_bus, 0x03, temp);
|
||||||
|
write_reg(i2c_bus, 0x19, sy>>2);
|
||||||
|
write_reg(i2c_bus, 0x1A, endy>>2);
|
||||||
|
|
||||||
|
read_reg(i2c_bus, 0x32, 1, &temp);
|
||||||
|
temp &= 0xC0;
|
||||||
|
temp |= ((endx & 0x07) << 3) | (sx & 0x07);
|
||||||
|
write_reg(i2c_bus, 0x32, temp);
|
||||||
|
write_reg(i2c_bus, 0x17, sx>>3);
|
||||||
|
write_reg(i2c_bus, 0x18, endx>>3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the image output size */
|
||||||
|
rt_uint8_t ov2640_set_image_out_size(rt_uint16_t width,rt_uint16_t height)
|
||||||
|
{
|
||||||
|
rt_uint16_t outh, outw;
|
||||||
|
rt_uint8_t temp;
|
||||||
|
|
||||||
|
if(width%4)return 1;
|
||||||
|
if(height%4)return 2;
|
||||||
|
outw = width / 4;
|
||||||
|
outh = height / 4;
|
||||||
|
write_reg(i2c_bus, 0xFF, 0x00);
|
||||||
|
write_reg(i2c_bus, 0xE0, 0x04);
|
||||||
|
write_reg(i2c_bus, 0x5A, outw & 0XFF);
|
||||||
|
write_reg(i2c_bus, 0x5B, outh & 0XFF);
|
||||||
|
temp = (outw >> 8) & 0x03;
|
||||||
|
temp |= (outh >> 6) & 0x04;
|
||||||
|
write_reg(i2c_bus, 0x5C, temp);
|
||||||
|
write_reg(i2c_bus, 0xE0, 0X00);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the image window size */
|
||||||
|
rt_uint8_t ov2640_set_image_window_size(rt_uint16_t offx, rt_uint16_t offy, rt_uint16_t width, rt_uint16_t height)
|
||||||
|
{
|
||||||
|
rt_uint16_t hsize, vsize;
|
||||||
|
rt_uint8_t temp;
|
||||||
|
if ((width % 4) || (height%4))
|
||||||
|
{
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
hsize = width / 4;
|
||||||
|
vsize = height / 4;
|
||||||
|
write_reg(i2c_bus, 0XFF,0X00);
|
||||||
|
write_reg(i2c_bus, 0XE0,0X04);
|
||||||
|
write_reg(i2c_bus, 0X51,hsize&0XFF);
|
||||||
|
write_reg(i2c_bus, 0X52,vsize&0XFF);
|
||||||
|
write_reg(i2c_bus, 0X53,offx&0XFF);
|
||||||
|
write_reg(i2c_bus, 0X54,offy&0XFF);
|
||||||
|
temp=(vsize>>1)&0X80;
|
||||||
|
temp|=(offy>>4)&0X70;
|
||||||
|
temp|=(hsize>>5)&0X08;
|
||||||
|
temp|=(offx>>8)&0X07;
|
||||||
|
write_reg(i2c_bus, 0X55,temp);
|
||||||
|
write_reg(i2c_bus, 0X57,(hsize>>2)&0X80);
|
||||||
|
write_reg(i2c_bus, 0XE0,0X00);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set output resolution */
|
||||||
|
rt_uint8_t ov2640_set_image_size(rt_uint16_t width ,rt_uint16_t height)
|
||||||
|
{
|
||||||
|
rt_uint8_t temp;
|
||||||
|
write_reg(i2c_bus, 0xFF, 0x00);
|
||||||
|
write_reg(i2c_bus, 0xE0, 0x04);
|
||||||
|
write_reg(i2c_bus, 0xC0, (width >>3) & 0xFF);
|
||||||
|
write_reg(i2c_bus, 0xC1, (height >> 3) & 0xFF);
|
||||||
|
temp = (width & 0x07) << 3;
|
||||||
|
temp |= height & 0x07;
|
||||||
|
temp |= (width >> 4) & 0x80;
|
||||||
|
write_reg(i2c_bus, 0x8C, temp);
|
||||||
|
write_reg(i2c_bus, 0xE0, 0x00);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void camera_dma_data_process(void)
|
||||||
|
{
|
||||||
|
rt_uint16_t i;
|
||||||
|
rt_uint32_t *pbuf;
|
||||||
|
pbuf = jpeg_data_buf + jpeg_data_len;
|
||||||
|
|
||||||
|
if (DMA2_Stream1->CR & (1<<19))
|
||||||
|
{
|
||||||
|
for (i = 0; i < JPEG_LINE_SIZE; i++)
|
||||||
|
{
|
||||||
|
pbuf[i] = JPEG_LINE0_BUF[i];
|
||||||
|
}
|
||||||
|
jpeg_data_len += JPEG_LINE_SIZE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < JPEG_LINE_SIZE; i++)
|
||||||
|
{
|
||||||
|
pbuf[i] = JPEG_LINE1_BUF[i];
|
||||||
|
}
|
||||||
|
jpeg_data_len += JPEG_LINE_SIZE;
|
||||||
|
}
|
||||||
|
SCB_CleanInvalidateDCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* After a frame of picture data has been collected. */
|
||||||
|
void camera_frame_data_process(void)
|
||||||
|
{
|
||||||
|
rt_uint16_t i, rlen;
|
||||||
|
rt_uint32_t *pbuf = RT_NULL;
|
||||||
|
|
||||||
|
if (jpeg_data_ok == 0)
|
||||||
|
{
|
||||||
|
DMA2_Stream1->CR &= ~(1<<0);
|
||||||
|
while(DMA2_Stream1->CR & 0x01);
|
||||||
|
|
||||||
|
rlen = JPEG_LINE_SIZE - DMA2_Stream1->NDTR;
|
||||||
|
pbuf = jpeg_data_buf + jpeg_data_len;
|
||||||
|
|
||||||
|
if (DMA2_Stream1->CR & (1<<19))
|
||||||
|
{
|
||||||
|
for (i = 0; i < rlen; i++)
|
||||||
|
{
|
||||||
|
pbuf[i] = JPEG_LINE1_BUF[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < rlen; i++)
|
||||||
|
{
|
||||||
|
pbuf[i] = JPEG_LINE0_BUF[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jpeg_data_len += rlen;
|
||||||
|
jpeg_data_ok = 1;
|
||||||
|
}
|
||||||
|
if (jpeg_data_ok==2)
|
||||||
|
{
|
||||||
|
DMA2_Stream1->NDTR = JPEG_LINE_SIZE;
|
||||||
|
DMA2_Stream1->CR |= 1<<0;
|
||||||
|
jpeg_data_ok = 0;
|
||||||
|
jpeg_data_len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ov2640_pwdn_set(rt_uint8_t sta)
|
||||||
|
{
|
||||||
|
if (pcf_dev == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("can't find pcf8574 device!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pcf8574_pin_write(pcf_dev, DCMI_PWDN_IO, sta);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sw_ov2640_mode(void)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_Initure = {0};
|
||||||
|
|
||||||
|
ov2640_pwdn_set(0);
|
||||||
|
|
||||||
|
GPIO_Initure.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_11;
|
||||||
|
GPIO_Initure.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_Initure.Pull = GPIO_PULLUP;
|
||||||
|
GPIO_Initure.Speed = GPIO_SPEED_HIGH;
|
||||||
|
GPIO_Initure.Alternate = GPIO_AF13_DCMI;
|
||||||
|
HAL_GPIO_Init(GPIOC,&GPIO_Initure);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sw_sdcard_mode(void)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_Initure = {0};
|
||||||
|
|
||||||
|
ov2640_pwdn_set(1); /* OV2640 Power Down */
|
||||||
|
|
||||||
|
GPIO_Initure.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_11;
|
||||||
|
GPIO_Initure.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_Initure.Pull = GPIO_PULLUP;
|
||||||
|
GPIO_Initure.Speed = GPIO_SPEED_HIGH;
|
||||||
|
GPIO_Initure.Alternate = GPIO_AF12_SDMMC1;
|
||||||
|
HAL_GPIO_Init(GPIOC, &GPIO_Initure);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rt_ov2640_init(void)
|
||||||
|
{
|
||||||
|
rt_uint16_t i = 0;
|
||||||
|
rt_err_t result = RT_EOK;
|
||||||
|
rt_device_t dcmi_dev = RT_NULL;
|
||||||
|
|
||||||
|
sw_ov2640_mode();
|
||||||
|
pcf_dev = pcf8574_init("i2c1", RT_NULL);
|
||||||
|
if (pcf_dev == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("can't find pcf8574, please check it");
|
||||||
|
return -RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ov2640_pwdn_set(0);
|
||||||
|
rt_thread_delay(20);
|
||||||
|
|
||||||
|
/* ov2640 hard reset */
|
||||||
|
rt_pin_mode(RESET_PIN, PIN_MODE_OUTPUT);
|
||||||
|
rt_pin_write(RESET_PIN, PIN_LOW);
|
||||||
|
rt_thread_delay(20);
|
||||||
|
rt_pin_write(RESET_PIN, PIN_HIGH);
|
||||||
|
rt_thread_delay(20);
|
||||||
|
|
||||||
|
i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
|
||||||
|
if (i2c_bus == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("can't find %s deivce", I2C_NAME);
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
/* Prepare the camera to be configured */
|
||||||
|
result = write_reg(i2c_bus, OV2640_DSP_RA_DLMT, 0x01);
|
||||||
|
if (result != RT_EOK )
|
||||||
|
{
|
||||||
|
LOG_E("ov2640 write reg error!");
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
rt_thread_delay(10);
|
||||||
|
result = write_reg(i2c_bus, OV2640_SENSOR_COM7, 0x80);
|
||||||
|
if (result != RT_EOK)
|
||||||
|
{
|
||||||
|
LOG_E("ov2640 soft reset error!");
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
rt_thread_delay(20);
|
||||||
|
|
||||||
|
result = ov2640_read_id(i2c_bus);
|
||||||
|
if (result != RT_EOK )
|
||||||
|
{
|
||||||
|
LOG_E("ov2640 read id error!");
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(ov2640_svga_init_reg_tbl) / 2; i++)
|
||||||
|
{
|
||||||
|
write_reg(i2c_bus, ov2640_svga_init_reg_tbl[i][0], ov2640_svga_init_reg_tbl[i][1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ov2640_rgb565_mode();
|
||||||
|
ov2640_set_light_mode(0);
|
||||||
|
ov2640_set_color_saturation(3);
|
||||||
|
ov2640_set_brightness(4);
|
||||||
|
ov2640_set_contrast(3);
|
||||||
|
ov2640_jpeg_mode();
|
||||||
|
ov2640_set_image_window_size(0, 0, 320, 240);
|
||||||
|
ov2640_set_image_out_size(320, 240);
|
||||||
|
|
||||||
|
dcmi_dev = rt_device_find("dcmi");
|
||||||
|
if (dcmi_dev == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("can't find dcmi device!");
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
rt_device_open(dcmi_dev, RT_DEVICE_FLAG_RDWR);
|
||||||
|
|
||||||
|
jpeg_data_buf = rt_malloc(JPEG_BUF_SIZE);
|
||||||
|
if (RT_NULL == jpeg_data_buf)
|
||||||
|
{
|
||||||
|
rt_kprintf("jpeg data buf malloc error!\n");
|
||||||
|
return RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start dcmi capture */
|
||||||
|
rt_hw_dcmi_dma_config((rt_uint32_t)JPEG_LINE0_BUF, (rt_uint32_t)JPEG_LINE1_BUF, JPEG_LINE_SIZE);
|
||||||
|
|
||||||
|
rt_kprintf("camera init success!\n");
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
INIT_APP_EXPORT(rt_ov2640_init);
|
||||||
|
|
||||||
|
int camera_sample(int argc, char **argv)
|
||||||
|
{
|
||||||
|
rt_err_t result = RT_EOK;
|
||||||
|
int fd = -1;
|
||||||
|
rt_uint32_t i, jpg_start, jpg_len;
|
||||||
|
rt_uint8_t jpg_head = 0;
|
||||||
|
rt_uint8_t *p = RT_NULL;
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
rt_kprintf("Usage:\n");
|
||||||
|
rt_kprintf("camera_sample file.jpg\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sw_ov2640_mode();
|
||||||
|
DCMI_Start();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
while (jpeg_data_ok != 1);
|
||||||
|
jpeg_data_ok = 2;
|
||||||
|
while (jpeg_data_ok != 1);
|
||||||
|
DCMI_Stop();
|
||||||
|
|
||||||
|
p = (rt_uint8_t *)jpeg_data_buf;
|
||||||
|
jpg_len = 0;
|
||||||
|
jpg_head = 0;
|
||||||
|
for (i = 0; i < jpeg_data_len * 4; i++)
|
||||||
|
{
|
||||||
|
/* jpg head */
|
||||||
|
if ((p[i] == 0xFF) && (p[i + 1] == 0xD8))
|
||||||
|
{
|
||||||
|
jpg_start = i;
|
||||||
|
jpg_head = 1;
|
||||||
|
}
|
||||||
|
/* jpg end */
|
||||||
|
if ((p[i] == 0xFF) && (p[i + 1] == 0xD9) && jpg_head)
|
||||||
|
{
|
||||||
|
jpg_len = i - jpg_start + 2; /* a picture len */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (jpg_len)
|
||||||
|
{
|
||||||
|
p += jpg_start;
|
||||||
|
sw_sdcard_mode();
|
||||||
|
fd = open(argv[1], O_WRONLY | O_CREAT);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
rt_kprintf("open file for recording failed!\n");
|
||||||
|
result = -RT_ERROR;
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
write(fd, p, jpg_len);
|
||||||
|
close(fd);
|
||||||
|
rt_kprintf("%s picture capture complate!\n", argv[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("jpg_len error!\n");
|
||||||
|
result = -RT_ERROR;
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
return result;;
|
||||||
|
}
|
||||||
|
MSH_CMD_EXPORT(camera_sample, record picture to a jpg file);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,778 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2020-07-27 thread-liu first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DRV_OV2640_H__
|
||||||
|
#define __DRV_OV2640_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <board.h>
|
||||||
|
|
||||||
|
#define OV2640_MID 0X7FA2
|
||||||
|
#define OV2640_PID 0X2642
|
||||||
|
|
||||||
|
|
||||||
|
//褰撻<E8A4B0>夋嫨DSP鍦板潃(0XFF=0X00)鏃<>,OV2640鐨凞SP瀵勫瓨鍣ㄥ湴鍧<E6B9B4>鏄犲皠琛<E79AA0>
|
||||||
|
#define OV2640_DSP_R_BYPASS 0x05
|
||||||
|
#define OV2640_DSP_Qs 0x44
|
||||||
|
#define OV2640_DSP_CTRL 0x50
|
||||||
|
#define OV2640_DSP_HSIZE1 0x51
|
||||||
|
#define OV2640_DSP_VSIZE1 0x52
|
||||||
|
#define OV2640_DSP_XOFFL 0x53
|
||||||
|
#define OV2640_DSP_YOFFL 0x54
|
||||||
|
#define OV2640_DSP_VHYX 0x55
|
||||||
|
#define OV2640_DSP_DPRP 0x56
|
||||||
|
#define OV2640_DSP_TEST 0x57
|
||||||
|
#define OV2640_DSP_ZMOW 0x5A
|
||||||
|
#define OV2640_DSP_ZMOH 0x5B
|
||||||
|
#define OV2640_DSP_ZMHH 0x5C
|
||||||
|
#define OV2640_DSP_BPADDR 0x7C
|
||||||
|
#define OV2640_DSP_BPDATA 0x7D
|
||||||
|
#define OV2640_DSP_CTRL2 0x86
|
||||||
|
#define OV2640_DSP_CTRL3 0x87
|
||||||
|
#define OV2640_DSP_SIZEL 0x8C
|
||||||
|
#define OV2640_DSP_HSIZE2 0xC0
|
||||||
|
#define OV2640_DSP_VSIZE2 0xC1
|
||||||
|
#define OV2640_DSP_CTRL0 0xC2
|
||||||
|
#define OV2640_DSP_CTRL1 0xC3
|
||||||
|
#define OV2640_DSP_R_DVP_SP 0xD3
|
||||||
|
#define OV2640_DSP_IMAGE_MODE 0xDA
|
||||||
|
#define OV2640_DSP_RESET 0xE0
|
||||||
|
#define OV2640_DSP_MS_SP 0xF0
|
||||||
|
#define OV2640_DSP_SS_ID 0x7F
|
||||||
|
#define OV2640_DSP_SS_CTRL 0xF8
|
||||||
|
#define OV2640_DSP_MC_BIST 0xF9
|
||||||
|
#define OV2640_DSP_MC_AL 0xFA
|
||||||
|
#define OV2640_DSP_MC_AH 0xFB
|
||||||
|
#define OV2640_DSP_MC_D 0xFC
|
||||||
|
#define OV2640_DSP_P_STATUS 0xFE
|
||||||
|
#define OV2640_DSP_RA_DLMT 0xFF
|
||||||
|
|
||||||
|
//褰撻<E8A4B0>夋嫨浼犳劅鍣ㄥ湴鍧<E6B9B4>(0XFF=0X01)鏃<>,OV2640鐨凞SP瀵勫瓨鍣ㄥ湴鍧<E6B9B4>鏄犲皠琛<E79AA0>
|
||||||
|
#define OV2640_SENSOR_GAIN 0x00
|
||||||
|
#define OV2640_SENSOR_COM1 0x03
|
||||||
|
#define OV2640_SENSOR_REG04 0x04
|
||||||
|
#define OV2640_SENSOR_REG08 0x08
|
||||||
|
#define OV2640_SENSOR_COM2 0x09
|
||||||
|
#define OV2640_SENSOR_PIDH 0x0A
|
||||||
|
#define OV2640_SENSOR_PIDL 0x0B
|
||||||
|
#define OV2640_SENSOR_COM3 0x0C
|
||||||
|
#define OV2640_SENSOR_COM4 0x0D
|
||||||
|
#define OV2640_SENSOR_AEC 0x10
|
||||||
|
#define OV2640_SENSOR_CLKRC 0x11
|
||||||
|
#define OV2640_SENSOR_COM7 0x12
|
||||||
|
#define OV2640_SENSOR_COM8 0x13
|
||||||
|
#define OV2640_SENSOR_COM9 0x14
|
||||||
|
#define OV2640_SENSOR_COM10 0x15
|
||||||
|
#define OV2640_SENSOR_HREFST 0x17
|
||||||
|
#define OV2640_SENSOR_HREFEND 0x18
|
||||||
|
#define OV2640_SENSOR_VSTART 0x19
|
||||||
|
#define OV2640_SENSOR_VEND 0x1A
|
||||||
|
#define OV2640_SENSOR_MIDH 0x1C
|
||||||
|
#define OV2640_SENSOR_MIDL 0x1D
|
||||||
|
#define OV2640_SENSOR_AEW 0x24
|
||||||
|
#define OV2640_SENSOR_AEB 0x25
|
||||||
|
#define OV2640_SENSOR_W 0x26
|
||||||
|
#define OV2640_SENSOR_REG2A 0x2A
|
||||||
|
#define OV2640_SENSOR_FRARL 0x2B
|
||||||
|
#define OV2640_SENSOR_ADDVSL 0x2D
|
||||||
|
#define OV2640_SENSOR_ADDVHS 0x2E
|
||||||
|
#define OV2640_SENSOR_YAVG 0x2F
|
||||||
|
#define OV2640_SENSOR_REG32 0x32
|
||||||
|
#define OV2640_SENSOR_ARCOM2 0x34
|
||||||
|
#define OV2640_SENSOR_REG45 0x45
|
||||||
|
#define OV2640_SENSOR_FLL 0x46
|
||||||
|
#define OV2640_SENSOR_FLH 0x47
|
||||||
|
#define OV2640_SENSOR_COM19 0x48
|
||||||
|
#define OV2640_SENSOR_ZOOMS 0x49
|
||||||
|
#define OV2640_SENSOR_COM22 0x4B
|
||||||
|
#define OV2640_SENSOR_COM25 0x4E
|
||||||
|
#define OV2640_SENSOR_BD50 0x4F
|
||||||
|
#define OV2640_SENSOR_BD60 0x50
|
||||||
|
#define OV2640_SENSOR_REG5D 0x5D
|
||||||
|
#define OV2640_SENSOR_REG5E 0x5E
|
||||||
|
#define OV2640_SENSOR_REG5F 0x5F
|
||||||
|
#define OV2640_SENSOR_REG60 0x60
|
||||||
|
#define OV2640_SENSOR_HISTO_LOW 0x61
|
||||||
|
#define OV2640_SENSOR_HISTO_HIGH 0x62
|
||||||
|
|
||||||
|
/* Automatic exposure setting parameters table, support 5 levels */
|
||||||
|
const rt_uint8_t OV2640_AUTOEXPOSURE_LEVEL[5][8]=
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0xFF,0x01,
|
||||||
|
0x24,0x20,
|
||||||
|
0x25,0x18,
|
||||||
|
0x26,0x60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xFF,0x01,
|
||||||
|
0x24,0x34,
|
||||||
|
0x25,0x1c,
|
||||||
|
0x26,0x00,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xFF,0x01,
|
||||||
|
0x24,0x3e,
|
||||||
|
0x25,0x38,
|
||||||
|
0x26,0x81,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xFF,0x01,
|
||||||
|
0x24,0x48,
|
||||||
|
0x25,0x40,
|
||||||
|
0x26,0x81,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xFF,0x01,
|
||||||
|
0x24,0x58,
|
||||||
|
0x25,0x50,
|
||||||
|
0x26,0x92,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const rt_uint8_t ov2640_sxga_init_reg_tbl[][2]=
|
||||||
|
{
|
||||||
|
{0xff, 0x00},
|
||||||
|
{0x2c, 0xff},
|
||||||
|
{0x2e, 0xdf},
|
||||||
|
{0xff, 0x01},
|
||||||
|
{0x3c, 0x32},
|
||||||
|
{0x11, 0x00},
|
||||||
|
{0x09, 0x02},
|
||||||
|
{0x04, 0xD8},
|
||||||
|
{0x13, 0xe5},
|
||||||
|
{0x14, 0x48},
|
||||||
|
{0x2c, 0x0c},
|
||||||
|
{0x33, 0x78},
|
||||||
|
{0x3a, 0x33},
|
||||||
|
{0x3b, 0xfB},
|
||||||
|
{0x3e, 0x00},
|
||||||
|
{0x43, 0x11},
|
||||||
|
{0x16, 0x10},
|
||||||
|
{0x39, 0x92},
|
||||||
|
{0x35, 0xda},
|
||||||
|
{0x22, 0x1a},
|
||||||
|
{0x37, 0xc3},
|
||||||
|
{0x23, 0x00},
|
||||||
|
{0x34, 0xc0},
|
||||||
|
{0x36, 0x1a},
|
||||||
|
{0x06, 0x88},
|
||||||
|
{0x07, 0xc0},
|
||||||
|
{0x0d, 0x87},
|
||||||
|
{0x0e, 0x41},
|
||||||
|
{0x4c, 0x00},
|
||||||
|
{0x48, 0x00},
|
||||||
|
{0x5B, 0x00},
|
||||||
|
{0x42, 0x03},
|
||||||
|
{0x4a, 0x81},
|
||||||
|
{0x21, 0x99},
|
||||||
|
{0x24, 0x40},
|
||||||
|
{0x25, 0x38},
|
||||||
|
{0x26, 0x82},
|
||||||
|
{0x5c, 0x00},
|
||||||
|
{0x63, 0x00},
|
||||||
|
{0x46, 0x00},
|
||||||
|
{0x0c, 0x3c},
|
||||||
|
{0x61, 0x70},
|
||||||
|
{0x62, 0x80},
|
||||||
|
{0x7c, 0x05},
|
||||||
|
{0x20, 0x80},
|
||||||
|
{0x28, 0x30},
|
||||||
|
{0x6c, 0x00},
|
||||||
|
{0x6d, 0x80},
|
||||||
|
{0x6e, 0x00},
|
||||||
|
{0x70, 0x02},
|
||||||
|
{0x71, 0x94},
|
||||||
|
{0x73, 0xc1},
|
||||||
|
{0x3d, 0x34},
|
||||||
|
{0x5a, 0x57},
|
||||||
|
{0x12, 0x00},
|
||||||
|
{0x17, 0x11},
|
||||||
|
{0x18, 0x75},
|
||||||
|
{0x19, 0x01},
|
||||||
|
{0x1a, 0x97},
|
||||||
|
{0x32, 0x36},
|
||||||
|
{0x03, 0x0f},
|
||||||
|
{0x37, 0x40},
|
||||||
|
{0x4f, 0xca},
|
||||||
|
{0x50, 0xa8},
|
||||||
|
{0x5a, 0x23},
|
||||||
|
{0x6d, 0x00},
|
||||||
|
{0x6d, 0x38},
|
||||||
|
{0xff, 0x00},
|
||||||
|
{0xe5, 0x7f},
|
||||||
|
{0xf9, 0xc0},
|
||||||
|
{0x41, 0x24},
|
||||||
|
{0xe0, 0x14},
|
||||||
|
{0x76, 0xff},
|
||||||
|
{0x33, 0xa0},
|
||||||
|
{0x42, 0x20},
|
||||||
|
{0x43, 0x18},
|
||||||
|
{0x4c, 0x00},
|
||||||
|
{0x87, 0xd5},
|
||||||
|
{0x88, 0x3f},
|
||||||
|
{0xd7, 0x03},
|
||||||
|
{0xd9, 0x10},
|
||||||
|
{0xd3, 0x82},
|
||||||
|
{0xc8, 0x08},
|
||||||
|
{0xc9, 0x80},
|
||||||
|
{0x7c, 0x00},
|
||||||
|
{0x7d, 0x00},
|
||||||
|
{0x7c, 0x03},
|
||||||
|
{0x7d, 0x48},
|
||||||
|
{0x7d, 0x48},
|
||||||
|
{0x7c, 0x08},
|
||||||
|
{0x7d, 0x20},
|
||||||
|
{0x7d, 0x10},
|
||||||
|
{0x7d, 0x0e},
|
||||||
|
{0x90, 0x00},
|
||||||
|
{0x91, 0x0e},
|
||||||
|
{0x91, 0x1a},
|
||||||
|
{0x91, 0x31},
|
||||||
|
{0x91, 0x5a},
|
||||||
|
{0x91, 0x69},
|
||||||
|
{0x91, 0x75},
|
||||||
|
{0x91, 0x7e},
|
||||||
|
{0x91, 0x88},
|
||||||
|
{0x91, 0x8f},
|
||||||
|
{0x91, 0x96},
|
||||||
|
{0x91, 0xa3},
|
||||||
|
{0x91, 0xaf},
|
||||||
|
{0x91, 0xc4},
|
||||||
|
{0x91, 0xd7},
|
||||||
|
{0x91, 0xe8},
|
||||||
|
{0x91, 0x20},
|
||||||
|
{0x92, 0x00},
|
||||||
|
{0x93, 0x06},
|
||||||
|
{0x93, 0xe3},
|
||||||
|
{0x93, 0x05},
|
||||||
|
{0x93, 0x05},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x04},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x96, 0x00},
|
||||||
|
{0x97, 0x08},
|
||||||
|
{0x97, 0x19},
|
||||||
|
{0x97, 0x02},
|
||||||
|
{0x97, 0x0c},
|
||||||
|
{0x97, 0x24},
|
||||||
|
{0x97, 0x30},
|
||||||
|
{0x97, 0x28},
|
||||||
|
{0x97, 0x26},
|
||||||
|
{0x97, 0x02},
|
||||||
|
{0x97, 0x98},
|
||||||
|
{0x97, 0x80},
|
||||||
|
{0x97, 0x00},
|
||||||
|
{0x97, 0x00},
|
||||||
|
{0xc3, 0xef},
|
||||||
|
{0xa4, 0x00},
|
||||||
|
{0xa8, 0x00},
|
||||||
|
{0xc5, 0x11},
|
||||||
|
{0xc6, 0x51},
|
||||||
|
{0xbf, 0x80},
|
||||||
|
{0xc7, 0x10},
|
||||||
|
{0xb6, 0x66},
|
||||||
|
{0xb8, 0xA5},
|
||||||
|
{0xb7, 0x64},
|
||||||
|
{0xb9, 0x7C},
|
||||||
|
{0xb3, 0xaf},
|
||||||
|
{0xb4, 0x97},
|
||||||
|
{0xb5, 0xFF},
|
||||||
|
{0xb0, 0xC5},
|
||||||
|
{0xb1, 0x94},
|
||||||
|
{0xb2, 0x0f},
|
||||||
|
{0xc4, 0x5c},
|
||||||
|
{0xc0, 0xc8},
|
||||||
|
{0xc1, 0x96},
|
||||||
|
{0x8c, 0x00},
|
||||||
|
{0x86, 0x3d},
|
||||||
|
{0x50, 0x00},
|
||||||
|
{0x51, 0x90},
|
||||||
|
{0x52, 0x2c},
|
||||||
|
{0x53, 0x00},
|
||||||
|
{0x54, 0x00},
|
||||||
|
{0x55, 0x88},
|
||||||
|
{0x5a, 0x90},
|
||||||
|
{0x5b, 0x2C},
|
||||||
|
{0x5c, 0x05},
|
||||||
|
{0xd3, 0x02},
|
||||||
|
{0xc3, 0xed},
|
||||||
|
{0x7f, 0x00},
|
||||||
|
{0xda, 0x09},
|
||||||
|
{0xe5, 0x1f},
|
||||||
|
{0xe1, 0x67},
|
||||||
|
{0xe0, 0x00},
|
||||||
|
{0xdd, 0x7f},
|
||||||
|
{0x05, 0x00},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SVGA 800*600 */
|
||||||
|
const rt_uint8_t ov2640_svga_init_reg_tbl[][2]=
|
||||||
|
{
|
||||||
|
{0xff, 0x00},
|
||||||
|
{0x2c, 0xff},
|
||||||
|
{0x2e, 0xdf},
|
||||||
|
{0xff, 0x01},
|
||||||
|
{0x3c, 0x32},
|
||||||
|
{0x11, 0x00},
|
||||||
|
{0x09, 0x02},
|
||||||
|
{0x04, 0xD8},
|
||||||
|
{0x13, 0xe5},
|
||||||
|
{0x14, 0x48},
|
||||||
|
{0x2c, 0x0c},
|
||||||
|
{0x33, 0x78},
|
||||||
|
{0x3a, 0x33},
|
||||||
|
{0x3b, 0xfB},
|
||||||
|
{0x3e, 0x00},
|
||||||
|
{0x43, 0x11},
|
||||||
|
{0x16, 0x10},
|
||||||
|
{0x39, 0x92},
|
||||||
|
{0x35, 0xda},
|
||||||
|
{0x22, 0x1a},
|
||||||
|
{0x37, 0xc3},
|
||||||
|
{0x23, 0x00},
|
||||||
|
{0x34, 0xc0},
|
||||||
|
{0x36, 0x1a},
|
||||||
|
{0x06, 0x88},
|
||||||
|
{0x07, 0xc0},
|
||||||
|
{0x0d, 0x87},
|
||||||
|
{0x0e, 0x41},
|
||||||
|
{0x4c, 0x00},
|
||||||
|
{0x48, 0x00},
|
||||||
|
{0x5B, 0x00},
|
||||||
|
{0x42, 0x03},
|
||||||
|
{0x4a, 0x81},
|
||||||
|
{0x21, 0x99},
|
||||||
|
{0x24, 0x40},
|
||||||
|
{0x25, 0x38},
|
||||||
|
{0x26, 0x82},
|
||||||
|
{0x5c, 0x00},
|
||||||
|
{0x63, 0x00},
|
||||||
|
{0x46, 0x22},
|
||||||
|
{0x0c, 0x3c},
|
||||||
|
{0x61, 0x70},
|
||||||
|
{0x62, 0x80},
|
||||||
|
{0x7c, 0x05},
|
||||||
|
{0x20, 0x80},
|
||||||
|
{0x28, 0x30},
|
||||||
|
{0x6c, 0x00},
|
||||||
|
{0x6d, 0x80},
|
||||||
|
{0x6e, 0x00},
|
||||||
|
{0x70, 0x02},
|
||||||
|
{0x71, 0x94},
|
||||||
|
{0x73, 0xc1},
|
||||||
|
{0x3d, 0x34},
|
||||||
|
{0x5a, 0x57},
|
||||||
|
{0x12, 0x40},
|
||||||
|
{0x17, 0x11},
|
||||||
|
{0x18, 0x43},
|
||||||
|
{0x19, 0x00},
|
||||||
|
{0x1a, 0x4b},
|
||||||
|
{0x32, 0x09},
|
||||||
|
{0x37, 0xc0},
|
||||||
|
{0x4f, 0xca},
|
||||||
|
{0x50, 0xa8},
|
||||||
|
{0x5a, 0x23},
|
||||||
|
{0x6d, 0x00},
|
||||||
|
{0x3d, 0x38},
|
||||||
|
{0xff, 0x00},
|
||||||
|
{0xe5, 0x7f},
|
||||||
|
{0xf9, 0xc0},
|
||||||
|
{0x41, 0x24},
|
||||||
|
{0xe0, 0x14},
|
||||||
|
{0x76, 0xff},
|
||||||
|
{0x33, 0xa0},
|
||||||
|
{0x42, 0x20},
|
||||||
|
{0x43, 0x18},
|
||||||
|
{0x4c, 0x00},
|
||||||
|
{0x87, 0xd5},
|
||||||
|
{0x88, 0x3f},
|
||||||
|
{0xd7, 0x03},
|
||||||
|
{0xd9, 0x10},
|
||||||
|
{0xd3, 0x82},
|
||||||
|
{0xc8, 0x08},
|
||||||
|
{0xc9, 0x80},
|
||||||
|
{0x7c, 0x00},
|
||||||
|
{0x7d, 0x00},
|
||||||
|
{0x7c, 0x03},
|
||||||
|
{0x7d, 0x48},
|
||||||
|
{0x7d, 0x48},
|
||||||
|
{0x7c, 0x08},
|
||||||
|
{0x7d, 0x20},
|
||||||
|
{0x7d, 0x10},
|
||||||
|
{0x7d, 0x0e},
|
||||||
|
{0x90, 0x00},
|
||||||
|
{0x91, 0x0e},
|
||||||
|
{0x91, 0x1a},
|
||||||
|
{0x91, 0x31},
|
||||||
|
{0x91, 0x5a},
|
||||||
|
{0x91, 0x69},
|
||||||
|
{0x91, 0x75},
|
||||||
|
{0x91, 0x7e},
|
||||||
|
{0x91, 0x88},
|
||||||
|
{0x91, 0x8f},
|
||||||
|
{0x91, 0x96},
|
||||||
|
{0x91, 0xa3},
|
||||||
|
{0x91, 0xaf},
|
||||||
|
{0x91, 0xc4},
|
||||||
|
{0x91, 0xd7},
|
||||||
|
{0x91, 0xe8},
|
||||||
|
{0x91, 0x20},
|
||||||
|
{0x92, 0x00},
|
||||||
|
{0x93, 0x06},
|
||||||
|
{0x93, 0xe3},
|
||||||
|
{0x93, 0x05},
|
||||||
|
{0x93, 0x05},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x04},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x96, 0x00},
|
||||||
|
{0x97, 0x08},
|
||||||
|
{0x97, 0x19},
|
||||||
|
{0x97, 0x02},
|
||||||
|
{0x97, 0x0c},
|
||||||
|
{0x97, 0x24},
|
||||||
|
{0x97, 0x30},
|
||||||
|
{0x97, 0x28},
|
||||||
|
{0x97, 0x26},
|
||||||
|
{0x97, 0x02},
|
||||||
|
{0x97, 0x98},
|
||||||
|
{0x97, 0x80},
|
||||||
|
{0x97, 0x00},
|
||||||
|
{0x97, 0x00},
|
||||||
|
{0xc3, 0xed},
|
||||||
|
{0xa4, 0x00},
|
||||||
|
{0xa8, 0x00},
|
||||||
|
{0xc5, 0x11},
|
||||||
|
{0xc6, 0x51},
|
||||||
|
{0xbf, 0x80},
|
||||||
|
{0xc7, 0x10},
|
||||||
|
{0xb6, 0x66},
|
||||||
|
{0xb8, 0xA5},
|
||||||
|
{0xb7, 0x64},
|
||||||
|
{0xb9, 0x7C},
|
||||||
|
{0xb3, 0xaf},
|
||||||
|
{0xb4, 0x97},
|
||||||
|
{0xb5, 0xFF},
|
||||||
|
{0xb0, 0xC5},
|
||||||
|
{0xb1, 0x94},
|
||||||
|
{0xb2, 0x0f},
|
||||||
|
{0xc4, 0x5c},
|
||||||
|
{0xc0, 0x64},
|
||||||
|
{0xc1, 0x4B},
|
||||||
|
{0x8c, 0x00},
|
||||||
|
{0x86, 0x3D},
|
||||||
|
{0x50, 0x00},
|
||||||
|
{0x51, 0xC8},
|
||||||
|
{0x52, 0x96},
|
||||||
|
{0x53, 0x00},
|
||||||
|
{0x54, 0x00},
|
||||||
|
{0x55, 0x00},
|
||||||
|
{0x5a, 0xC8},
|
||||||
|
{0x5b, 0x96},
|
||||||
|
{0x5c, 0x00},
|
||||||
|
{0xd3, 0x02},
|
||||||
|
{0xc3, 0xed},
|
||||||
|
{0x7f, 0x00},
|
||||||
|
{0xda, 0x09},
|
||||||
|
{0xe5, 0x1f},
|
||||||
|
{0xe1, 0x67},
|
||||||
|
{0xe0, 0x00},
|
||||||
|
{0xdd, 0x7f},
|
||||||
|
{0x05, 0x00},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Initialization sequence for QVGA resolution (320x240) */
|
||||||
|
const unsigned char OV2640_QVGA[][2]=
|
||||||
|
{
|
||||||
|
{0xff, 0x00},
|
||||||
|
{0x2c, 0xff},
|
||||||
|
{0x2e, 0xdf},
|
||||||
|
{0xff, 0x01},
|
||||||
|
{0x3c, 0x32},
|
||||||
|
{0x11, 0x00},
|
||||||
|
{0x09, 0x02},
|
||||||
|
{0x04, 0xA8},
|
||||||
|
{0x13, 0xe5},
|
||||||
|
{0x14, 0x48},
|
||||||
|
{0x2c, 0x0c},
|
||||||
|
{0x33, 0x78},
|
||||||
|
{0x3a, 0x33},
|
||||||
|
{0x3b, 0xfB},
|
||||||
|
{0x3e, 0x00},
|
||||||
|
{0x43, 0x11},
|
||||||
|
{0x16, 0x10},
|
||||||
|
{0x4a, 0x81},
|
||||||
|
{0x21, 0x99},
|
||||||
|
{0x24, 0x40},
|
||||||
|
{0x25, 0x38},
|
||||||
|
{0x26, 0x82},
|
||||||
|
{0x5c, 0x00},
|
||||||
|
{0x63, 0x00},
|
||||||
|
{0x46, 0x3f},
|
||||||
|
{0x0c, 0x3c},
|
||||||
|
{0x61, 0x70},
|
||||||
|
{0x62, 0x80},
|
||||||
|
{0x7c, 0x05},
|
||||||
|
{0x20, 0x80},
|
||||||
|
{0x28, 0x30},
|
||||||
|
{0x6c, 0x00},
|
||||||
|
{0x6d, 0x80},
|
||||||
|
{0x6e, 0x00},
|
||||||
|
{0x70, 0x02},
|
||||||
|
{0x71, 0x94},
|
||||||
|
{0x73, 0xc1},
|
||||||
|
{0x3d, 0x34},
|
||||||
|
{0x5a, 0x57},
|
||||||
|
{0x12, 0x00},
|
||||||
|
{0x11, 0x00},
|
||||||
|
{0x17, 0x11},
|
||||||
|
{0x18, 0x75},
|
||||||
|
{0x19, 0x01},
|
||||||
|
{0x1a, 0x97},
|
||||||
|
{0x32, 0x36},
|
||||||
|
{0x03, 0x0f},
|
||||||
|
{0x37, 0x40},
|
||||||
|
{0x4f, 0xbb},
|
||||||
|
{0x50, 0x9c},
|
||||||
|
{0x5a, 0x57},
|
||||||
|
{0x6d, 0x80},
|
||||||
|
{0x6d, 0x38},
|
||||||
|
{0x39, 0x02},
|
||||||
|
{0x35, 0x88},
|
||||||
|
{0x22, 0x0a},
|
||||||
|
{0x37, 0x40},
|
||||||
|
{0x23, 0x00},
|
||||||
|
{0x34, 0xa0},
|
||||||
|
{0x36, 0x1a},
|
||||||
|
{0x06, 0x02},
|
||||||
|
{0x07, 0xc0},
|
||||||
|
{0x0d, 0xb7},
|
||||||
|
{0x0e, 0x01},
|
||||||
|
{0x4c, 0x00},
|
||||||
|
{0xff, 0x00},
|
||||||
|
{0xe5, 0x7f},
|
||||||
|
{0xf9, 0xc0},
|
||||||
|
{0x41, 0x24},
|
||||||
|
{0xe0, 0x14},
|
||||||
|
{0x76, 0xff},
|
||||||
|
{0x33, 0xa0},
|
||||||
|
{0x42, 0x20},
|
||||||
|
{0x43, 0x18},
|
||||||
|
{0x4c, 0x00},
|
||||||
|
{0x87, 0xd0},
|
||||||
|
{0x88, 0x3f},
|
||||||
|
{0xd7, 0x03},
|
||||||
|
{0xd9, 0x10},
|
||||||
|
{0xd3, 0x82},
|
||||||
|
{0xc8, 0x08},
|
||||||
|
{0xc9, 0x80},
|
||||||
|
{0x7d, 0x00},
|
||||||
|
{0x7c, 0x03},
|
||||||
|
{0x7d, 0x48},
|
||||||
|
{0x7c, 0x08},
|
||||||
|
{0x7d, 0x20},
|
||||||
|
{0x7d, 0x10},
|
||||||
|
{0x7d, 0x0e},
|
||||||
|
{0x90, 0x00},
|
||||||
|
{0x91, 0x0e},
|
||||||
|
{0x91, 0x1a},
|
||||||
|
{0x91, 0x31},
|
||||||
|
{0x91, 0x5a},
|
||||||
|
{0x91, 0x69},
|
||||||
|
{0x91, 0x75},
|
||||||
|
{0x91, 0x7e},
|
||||||
|
{0x91, 0x88},
|
||||||
|
{0x91, 0x8f},
|
||||||
|
{0x91, 0x96},
|
||||||
|
{0x91, 0xa3},
|
||||||
|
{0x91, 0xaf},
|
||||||
|
{0x91, 0xc4},
|
||||||
|
{0x91, 0xd7},
|
||||||
|
{0x91, 0xe8},
|
||||||
|
{0x91, 0x20},
|
||||||
|
{0x92, 0x00},
|
||||||
|
{0x93, 0x06},
|
||||||
|
{0x93, 0xe3},
|
||||||
|
{0x93, 0x02},
|
||||||
|
{0x93, 0x02},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x04},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x03},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x96, 0x00},
|
||||||
|
{0x97, 0x08},
|
||||||
|
{0x97, 0x19},
|
||||||
|
{0x97, 0x02},
|
||||||
|
{0x97, 0x0c},
|
||||||
|
{0x97, 0x24},
|
||||||
|
{0x97, 0x30},
|
||||||
|
{0x97, 0x28},
|
||||||
|
{0x97, 0x26},
|
||||||
|
{0x97, 0x02},
|
||||||
|
{0x97, 0x98},
|
||||||
|
{0x97, 0x80},
|
||||||
|
{0x97, 0x00},
|
||||||
|
{0x97, 0x00},
|
||||||
|
{0xc3, 0xef},
|
||||||
|
{0xff, 0x00},
|
||||||
|
{0xba, 0xdc},
|
||||||
|
{0xbb, 0x08},
|
||||||
|
{0xb6, 0x24},
|
||||||
|
{0xb8, 0x33},
|
||||||
|
{0xb7, 0x20},
|
||||||
|
{0xb9, 0x30},
|
||||||
|
{0xb3, 0xb4},
|
||||||
|
{0xb4, 0xca},
|
||||||
|
{0xb5, 0x43},
|
||||||
|
{0xb0, 0x5c},
|
||||||
|
{0xb1, 0x4f},
|
||||||
|
{0xb2, 0x06},
|
||||||
|
{0xc7, 0x00},
|
||||||
|
{0xc6, 0x51},
|
||||||
|
{0xc5, 0x11},
|
||||||
|
{0xc4, 0x9c},
|
||||||
|
{0xbf, 0x00},
|
||||||
|
{0xbc, 0x64},
|
||||||
|
{0xa6, 0x00},
|
||||||
|
{0xa7, 0x1e},
|
||||||
|
{0xa7, 0x6b},
|
||||||
|
{0xa7, 0x47},
|
||||||
|
{0xa7, 0x33},
|
||||||
|
{0xa7, 0x00},
|
||||||
|
{0xa7, 0x23},
|
||||||
|
{0xa7, 0x2e},
|
||||||
|
{0xa7, 0x85},
|
||||||
|
{0xa7, 0x42},
|
||||||
|
{0xa7, 0x33},
|
||||||
|
{0xa7, 0x00},
|
||||||
|
{0xa7, 0x23},
|
||||||
|
{0xa7, 0x1b},
|
||||||
|
{0xa7, 0x74},
|
||||||
|
{0xa7, 0x42},
|
||||||
|
{0xa7, 0x33},
|
||||||
|
{0xa7, 0x00},
|
||||||
|
{0xa7, 0x23},
|
||||||
|
{0xc0, 0xc8},
|
||||||
|
{0xc1, 0x96},
|
||||||
|
{0x8c, 0x00},
|
||||||
|
{0x86, 0x3d},
|
||||||
|
{0x50, 0x92},
|
||||||
|
{0x51, 0x90},
|
||||||
|
{0x52, 0x2c},
|
||||||
|
{0x53, 0x00},
|
||||||
|
{0x54, 0x00},
|
||||||
|
{0x55, 0x88},
|
||||||
|
{0x5a, 0x50},
|
||||||
|
{0x5b, 0x3c},
|
||||||
|
{0x5c, 0x00},
|
||||||
|
{0xd3, 0x04},
|
||||||
|
{0x7f, 0x00},
|
||||||
|
{0xda, 0x00},
|
||||||
|
{0xe5, 0x1f},
|
||||||
|
{0xe1, 0x67},
|
||||||
|
{0xe0, 0x00},
|
||||||
|
{0xdd, 0x7f},
|
||||||
|
{0x05, 0x00},
|
||||||
|
{0xff, 0x00},
|
||||||
|
{0xe0, 0x04},
|
||||||
|
{0xc0, 0xc8},
|
||||||
|
{0xc1, 0x96},
|
||||||
|
{0x86, 0x3d},
|
||||||
|
{0x50, 0x92},
|
||||||
|
{0x51, 0x90},
|
||||||
|
{0x52, 0x2c},
|
||||||
|
{0x53, 0x00},
|
||||||
|
{0x54, 0x00},
|
||||||
|
{0x55, 0x88},
|
||||||
|
{0x57, 0x00},
|
||||||
|
{0x5a, 0x50},
|
||||||
|
{0x5b, 0x3C},
|
||||||
|
{0x5c, 0x00},
|
||||||
|
{0xd3, 0x08},
|
||||||
|
{0xe0, 0x00},
|
||||||
|
{0xFF, 0x00},
|
||||||
|
{0x05, 0x00},
|
||||||
|
{0xDA, 0x08},
|
||||||
|
{0xda, 0x09},
|
||||||
|
{0x98, 0x00},
|
||||||
|
{0x99, 0x00},
|
||||||
|
{0x00, 0x00},
|
||||||
|
};
|
||||||
|
|
||||||
|
const rt_uint8_t ov2640_jpeg_reg_tbl[][2]=
|
||||||
|
{
|
||||||
|
{0xff, 0x01},
|
||||||
|
{0xe0, 0x14},
|
||||||
|
{0xe1, 0x77},
|
||||||
|
{0xe5, 0x1f},
|
||||||
|
{0xd7, 0x03},
|
||||||
|
{0xda, 0x10},
|
||||||
|
{0xe0, 0x00},
|
||||||
|
};
|
||||||
|
|
||||||
|
const rt_uint8_t ov2640_rgb565_reg_tbl[][2]=
|
||||||
|
{
|
||||||
|
{0xFF, 0x00},
|
||||||
|
{0xDA, 0x09},
|
||||||
|
{0xD7, 0x03},
|
||||||
|
{0xDF, 0x02},
|
||||||
|
{0x33, 0xa0},
|
||||||
|
{0x3C, 0x00},
|
||||||
|
{0xe1, 0x67},
|
||||||
|
|
||||||
|
{0xff, 0x01},
|
||||||
|
{0xe0, 0x00},
|
||||||
|
{0xe1, 0x00},
|
||||||
|
{0xe5, 0x00},
|
||||||
|
{0xd7, 0x00},
|
||||||
|
{0xda, 0x00},
|
||||||
|
{0xe0, 0x00},
|
||||||
|
};
|
||||||
|
const rt_uint8_t ov2640_yuv422_reg_tbl[][2] =
|
||||||
|
{
|
||||||
|
{0xFF, 0x00},
|
||||||
|
{0xDA, 0x10},
|
||||||
|
{0xD7, 0x03},
|
||||||
|
{0xDF, 0x00},
|
||||||
|
{0x33, 0x80},
|
||||||
|
{0x3C, 0x40},
|
||||||
|
{0xe1, 0x77},
|
||||||
|
{0x00, 0x00},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue