add camera ov2640 support

This commit is contained in:
Neucrack
2019-03-29 19:29:36 +08:00
parent b4c85311f4
commit 04223e7ecb
15 changed files with 2090 additions and 3 deletions

View File

@@ -18,6 +18,7 @@ int main( void )
gpio_init();
sysctl_set_power_mode(SYSCTL_POWER_BANK6,SYSCTL_POWER_V18);
sysctl_set_power_mode(SYSCTL_POWER_BANK7,SYSCTL_POWER_V18);
sysctl_enable_irq();
setup();
do {

View File

@@ -0,0 +1,36 @@
#######################################
# Syntax Coloring Map
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
framesize_t KEYWORD1
pixformat_t KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
end KEYWORD2
run KEYWORD2
id KEYWORD2
snapshot KEYWORD2
getRGB565 KEYWORD2
getRGB888 KEYWORD2
setRotaion KEYWORD2
setInver KEYWORD2
width KEYWORD2
height KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
PIXFORMAT_RGB565 LITERAL1
FRAMESIZE_QQVGA LITERAL1
FRAMESIZE_QVGA LITERAL1
FRAMESIZE_VGA LITERAL1

View File

@@ -0,0 +1,9 @@
name=Camera
version=1.0
author=Neucrack
maintainer=Neucrack<Neucrack@Sipeed.com>
sentence=Camera interface
paragraph=Camera interface
category=Sensors
url=
architectures=k210

View File

@@ -0,0 +1,51 @@
#include "Camera.h"
static const int resolution[][2] = {
{0, 0 },
// C/SIF Resolutions
{88, 72 }, /* QQCIF */
{176, 144 }, /* QCIF */
{352, 288 }, /* CIF */
{88, 60 }, /* QQSIF */
{176, 120 }, /* QSIF */
{352, 240 }, /* SIF */
// VGA Resolutions
{40, 30 }, /* QQQQVGA */
{80, 60 }, /* QQQVGA */
{160, 120 }, /* QQVGA */
{320, 240 }, /* QVGA */
{640, 480 }, /* VGA */
{60, 40 }, /* HQQQVGA */
{120, 80 }, /* HQQVGA */
{240, 160 }, /* HQVGA */
// FFT Resolutions
{64, 32 }, /* 64x32 */
{64, 64 }, /* 64x64 */
{128, 64 }, /* 128x64 */
{128, 128 }, /* 128x64 */
// Other
{128, 160 }, /* LCD */
{128, 160 }, /* QQVGA2 */
{720, 480 }, /* WVGA */
{752, 480 }, /* WVGA2 */
{800, 600 }, /* SVGA */
{1280, 1024}, /* SXGA */
{1600, 1200}, /* UXGA */
};
Camera::Camera(framesize_t frameSize = FRAMESIZE_QVGA, pixformat_t pixFormat = PIXFORMAT_RGB565)
{
_frameSize = frameSize;
_pixFormat = pixFormat;
_width = resolution[frameSize][0];
_height = resolution[frameSize][1];
}
Camera::~Camera()
{
}

View File

@@ -0,0 +1,86 @@
#ifndef __CAMERA_H
#define __CAMERA_H
#include <stdint.h>
#include <stdbool.h>
typedef enum {
PIXFORMAT_INVLAID = 0,
PIXFORMAT_BAYER, // RAW
PIXFORMAT_RGB565, // RGB565
PIXFORMAT_YUV422, // YUV422
PIXFORMAT_GRAYSCALE, // GRAYSCALE
PIXFORMAT_JPEG, // JPEG/COMPRESSED
} pixformat_t;
typedef enum {
FRAMESIZE_INVALID = 0,
// C/SIF Resolutions
FRAMESIZE_QQCIF, // 88x72
FRAMESIZE_QCIF, // 176x144
FRAMESIZE_CIF, // 352x288
FRAMESIZE_QQSIF, // 88x60
FRAMESIZE_QSIF, // 176x120
FRAMESIZE_SIF, // 352x240
// VGA Resolutions
FRAMESIZE_QQQQVGA, // 40x30
FRAMESIZE_QQQVGA, // 80x60
FRAMESIZE_QQVGA, // 160x120
FRAMESIZE_QVGA, // 320x240
FRAMESIZE_VGA, // 640x480
FRAMESIZE_HQQQVGA, // 60x40
FRAMESIZE_HQQVGA, // 120x80
FRAMESIZE_HQVGA, // 240x160
// FFT Resolutions
FRAMESIZE_64X32, // 64x32
FRAMESIZE_64X64, // 64x64
FRAMESIZE_128X64, // 128x64
FRAMESIZE_128X128, // 128x128
// Other
FRAMESIZE_LCD, // 128x160
FRAMESIZE_QQVGA2, // 128x160
FRAMESIZE_WVGA, // 720x480
FRAMESIZE_WVGA2, // 752x480
FRAMESIZE_SVGA, // 800x600
FRAMESIZE_SXGA, // 1280x1024
FRAMESIZE_UXGA, // 1600x1200
} framesize_t;
class Camera{
public:
Camera(framesize_t frameSize, pixformat_t pixFormat);
~Camera();
virtual bool begin( ) = 0;
virtual void end() = 0;
// virtual bool reset() = 0;
// virtual bool setPixFormat(int pixFormat) = 0;
// virtual bool setFrameSize(int frameSize) = 0;
virtual bool run(bool run) = 0;
virtual int id() = 0;
/**
* @return pixels
* If pixels format is RGB565: return RGB565 pixels with every uint16_t one pixel, e.g. RED: 0xF800
*/
virtual uint8_t* snapshot() = 0;
virtual uint8_t* getRGB565(){ return 0; };
virtual uint8_t* getRGB888(){ return 0; };
virtual void setRotaion(uint8_t rotation) = 0;
virtual void setInvert(bool invert) = 0;
virtual int width(){ return _width; }
virtual int height(){ return _height; }
protected:
pixformat_t _pixFormat;
framesize_t _frameSize;
int _width;
int _height;
};
#endif

View File

@@ -0,0 +1,29 @@
#include <Sipeed_OV2640.h>
#include <Sipeed_ST7789.h>
#include <stdio.h>
SPIClass spi_(SPI0); // MUST be SPI0 for Maix series on board LCD
Sipeed_ST7789 lcd(320, 240, spi_);
Sipeed_OV2640 camera(FRAMESIZE_QVGA, PIXFORMAT_RGB565);
void setup()
{
lcd.begin(15000000, COLOR_RED);
if(!camera.begin())
printf("camera init fail\n");
else
printf("camera init success\n");
camera.run(true);
}
void loop()
{
uint8_t*img = camera.snapshot();
if(img == nullptr || img==0)
printf("snap fail\n");
else
lcd.drawImage(0, 0, camera.width(), camera.height(), (uint16_t*)img);
}

View File

@@ -0,0 +1,29 @@
#######################################
# Syntax Coloring Map
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
end KEYWORD2
reset KEYWORD2
setPixFormat KEYWORD2
setFrameSize KEYWORD2
run KEYWORD2
id KEYWORD2
snapshot KEYWORD2
setRotaion KEYWORD2
setInvert KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@@ -0,0 +1,9 @@
name=Sipeed_OV2640
version=1.0
author=Neucrack
maintainer=Neucrack<Neucrack@Sipeed.com>
sentence=Camera Sipeed_OV2640 driver
paragraph=Camera Sipeed_OV2640 driver
category=Sensors
url=
architectures=k210

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,109 @@
#ifndef __SIPEED_OV2640_H
#define __SIPEED_OV2640_H
#include "Camera.h"
#define OV9650_ID (0x96)
#define OV2640_ID (0x26)
#define OV7725_ID (0x77)
#define MT9V034_ID (0x13)
#define LEPTON_ID (0x54)
#define OV_CHIP_ID (0x0A)
#define ON_CHIP_ID (0x00)
#define GC0328_ID (0x9d)
#define GC0328_ADDR (0x42)
typedef enum {
GAINCEILING_2X,
GAINCEILING_4X,
GAINCEILING_8X,
GAINCEILING_16X,
GAINCEILING_32X,
GAINCEILING_64X,
GAINCEILING_128X,
} gainceiling_t;
typedef enum {
FRAMERATE_2FPS =0x9F,
FRAMERATE_8FPS =0x87,
FRAMERATE_15FPS=0x83,
FRAMERATE_30FPS=0x81,
FRAMERATE_60FPS=0x80,
} framerate_t;
class Sipeed_OV2640 : public Camera{
public:
Sipeed_OV2640(framesize_t frameSize = FRAMESIZE_QVGA, pixformat_t pixFormat = PIXFORMAT_RGB565);
~Sipeed_OV2640();
virtual bool begin();
virtual void end();
bool reset();
bool setPixFormat(pixformat_t pixFormat);
bool setFrameSize(framesize_t frameSize);
virtual bool run(bool run);
virtual int id();
/**
* @return pixels
* If pixels format is RGB565: return RGB565 pixels with every uint16_t one pixel, e.g. RED: 0xF800
*/
virtual uint8_t* snapshot();
virtual void setRotaion(uint8_t rotation);
virtual void setInvert(bool invert);
private:
uint8_t* _dataBuffer; // put RGB565 data
uint8_t* _aiBuffer; // put RGB888 data
uint8_t _resetPoliraty; // reset poliraty flag
uint8_t _pwdnPoliraty; // PWDN poliraty flag
uint8_t _slaveAddr; // camera address
uint8_t _id;
uint32_t _freq;
int dvpInit(uint32_t freq = 24000000);
int dvpInitIrq();
int cambus_scan();
int cambus_read_id(uint8_t addr,uint16_t *manuf_id, uint16_t *device_id);
int cambus_scan_gc0328(void);
int cambus_readb(uint8_t slv_addr, uint8_t reg_addr, uint8_t *reg_data);
int cambus_writeb(uint8_t slv_addr, uint8_t reg_addr, uint8_t reg_data);
int cambus_readw(uint8_t slv_addr, uint8_t reg_addr, uint16_t *reg_data);
int cambus_writew(uint8_t slv_addr, uint8_t reg_addr, uint16_t reg_data);
int cambus_readw2(uint8_t slv_addr, uint16_t reg_addr, uint16_t *reg_data);
int cambus_writew2(uint8_t slv_addr, uint16_t reg_addr, uint16_t reg_data);
int sensor_ov_detect();
int sensro_gc_detect();
int ov2640_reset();
int ov2640_read_reg(uint8_t reg_addr);
int ov2640_write_reg(uint8_t reg_addr, uint8_t reg_data);
int ov2640_set_pixformat(pixformat_t pixformat);
int ov2640_set_framesize(framesize_t framesize);
int ov2640_set_framerate(framerate_t framerate);
int ov2640_set_contrast(int level);
int ov2640_set_brightness(int level);
int ov2640_set_saturation(int level);
int ov2640_set_gainceiling( gainceiling_t gainceiling);
int ov2640_set_quality(int qs);
int ov2640_set_colorbar(int enable);
int ov2640_set_auto_gain(int enable, float gain_db, float gain_db_ceiling);
int ov2640_get_gain_db(float *gain_db);
int ov2640_set_auto_exposure(int enable, int exposure_us);
int ov2640_get_exposure_us(int *exposure_us);
int ov2640_set_auto_whitebal(int enable, float r_gain_db, float g_gain_db, float b_gain_db);
int ov2640_get_rgb_gain_db(float *r_gain_db, float *g_gain_db, float *b_gain_db);
int ov2640_set_hmirror(int enable);
int ov2640_set_vflip(int enable);
int sensor_snapshot( );
int reverse_u32pixel(uint32_t* addr,uint32_t length);
};
#endif

View File

@@ -0,0 +1,212 @@
/*
* This file is part of the OpenMV project.
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* OV2640 register definitions.
*/
#ifndef __REG_REGS_H__
#define __REG_REGS_H__
/* DSP register bank FF=0x00*/
#define QS 0x44
#define HSIZE 0x51
#define VSIZE 0x52
#define XOFFL 0x53
#define YOFFL 0x54
#define VHYX 0x55
#define DPRP 0x56
#define TEST 0x57
#define ZMOW 0x5A
#define ZMOH 0x5B
#define ZMHH 0x5C
#define BPADDR 0x7C
#define BPDATA 0x7D
#define SIZEL 0x8C
#define HSIZE8 0xC0
#define VSIZE8 0xC1
#define CTRL1 0xC3
#define MS_SP 0xF0
#define SS_ID 0xF7
#define SS_CTRL 0xF7
#define MC_AL 0xFA
#define MC_AH 0xFB
#define MC_D 0xFC
#define P_CMD 0xFD
#define P_STATUS 0xFE
#define CTRLI 0x50
#define CTRLI_LP_DP 0x80
#define CTRLI_ROUND 0x40
#define CTRL0 0xC2
#define CTRL0_AEC_EN 0x80
#define CTRL0_AEC_SEL 0x40
#define CTRL0_STAT_SEL 0x20
#define CTRL0_VFIRST 0x10
#define CTRL0_YUV422 0x08
#define CTRL0_YUV_EN 0x04
#define CTRL0_RGB_EN 0x02
#define CTRL0_RAW_EN 0x01
#define CTRL2 0x86
#define CTRL2_DCW_EN 0x20
#define CTRL2_SDE_EN 0x10
#define CTRL2_UV_ADJ_EN 0x08
#define CTRL2_UV_AVG_EN 0x04
#define CTRL2_CMX_EN 0x01
#define CTRL3 0x87
#define CTRL3_BPC_EN 0x80
#define CTRL3_WPC_EN 0x40
#define R_DVP_SP 0xD3
#define R_DVP_SP_AUTO_MODE 0x80
#define R_BYPASS 0x05
#define R_BYPASS_DSP_EN 0x00
#define R_BYPASS_DSP_BYPAS 0x01
#define IMAGE_MODE 0xDA
#define IMAGE_MODE_Y8_DVP_EN 0x40
#define IMAGE_MODE_JPEG_EN 0x10
#define IMAGE_MODE_YUV422 0x00
#define IMAGE_MODE_RAW10 0x04
#define IMAGE_MODE_RGB565 0x08
#define IMAGE_MODE_HREF_VSYNC 0x02
#define IMAGE_MODE_LBYTE_FIRST 0x01
#define IMAGE_MODE_GET_FMT(x) ((x)&0xC)
#define RESET 0xE0
#define RESET_MICROC 0x40
#define RESET_SCCB 0x20
#define RESET_JPEG 0x10
#define RESET_DVP 0x04
#define RESET_IPU 0x02
#define RESET_CIF 0x01
#define MC_BIST 0xF9
#define MC_BIST_RESET 0x80
#define MC_BIST_BOOT_ROM_SEL 0x40
#define MC_BIST_12KB_SEL 0x20
#define MC_BIST_12KB_MASK 0x30
#define MC_BIST_512KB_SEL 0x08
#define MC_BIST_512KB_MASK 0x0C
#define MC_BIST_BUSY_BIT_R 0x02
#define MC_BIST_MC_RES_ONE_SH_W 0x02
#define MC_BIST_LAUNCH 0x01
#define BANK_SEL 0xFF
#define BANK_SEL_DSP 0x00
#define BANK_SEL_SENSOR 0x01
/* Sensor register bank FF=0x01*/
#define GAIN 0x00
#define COM1 0x03
#define REG_PID 0x0A
#define REG_VER 0x0B
#define COM4 0x0D
#define AEC 0x10
#define CLKRC 0x11
#define CLKRC_DOUBLE 0x80
#define CLKRC_DIVIDER_MASK 0x3F
#define COM10 0x15
#define HSTART 0x17
#define HSTOP 0x18
#define VSTART 0x19
#define VSTOP 0x1A
#define MIDH 0x1C
#define MIDL 0x1D
#define AEW 0x24
#define AEB 0x25
#define REG2A 0x2A
#define FRARL 0x2B
#define ADDVSL 0x2D
#define ADDVSH 0x2E
#define YAVG 0x2F
#define HSDY 0x30
#define HEDY 0x31
#define ARCOM2 0x34
#define REG45 0x45
#define FLL 0x46
#define FLH 0x47
#define COM19 0x48
#define ZOOMS 0x49
#define COM22 0x4B
#define COM25 0x4E
#define BD50 0x4F
#define BD60 0x50
#define REG5D 0x5D
#define REG5E 0x5E
#define REG5F 0x5F
#define REG60 0x60
#define HISTO_LOW 0x61
#define HISTO_HIGH 0x62
#define REG04 0x04
#define REG04_DEFAULT 0x28
#define REG04_HFLIP_IMG 0x80
#define REG04_VFLIP_IMG 0x40
#define REG04_VREF_EN 0x10
#define REG04_HREF_EN 0x08
#define REG04_SET(x) (REG04_DEFAULT|x)
#define REG08 0x08
#define COM2 0x09
#define COM2_STDBY 0x10
#define COM2_OUT_DRIVE_1x 0x00
#define COM2_OUT_DRIVE_2x 0x01
#define COM2_OUT_DRIVE_3x 0x02
#define COM2_OUT_DRIVE_4x 0x03
#define COM3 0x0C
#define COM3_DEFAULT 0x38
#define COM3_BAND_50Hz 0x04
#define COM3_BAND_60Hz 0x00
#define COM3_BAND_AUTO 0x02
#define COM3_BAND_SET(x) (COM3_DEFAULT|x)
#define COM7 0x12
#define COM7_SRST 0x80
#define COM7_RES_UXGA 0x00 /* UXGA */
#define COM7_RES_SVGA 0x40 /* SVGA */
#define COM7_RES_CIF 0x20 /* CIF */
#define COM7_ZOOM_EN 0x04 /* Enable Zoom */
#define COM7_COLOR_BAR 0x02 /* Enable Color Bar Test */
#define COM7_GET_RES(x) ((x)&0x70)
#define COM8 0x13
#define COM8_DEFAULT 0xC0
#define COM8_BNDF_EN 0x20 /* Enable Banding filter */
#define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */
#define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */
#define COM8_SET(x) (COM8_DEFAULT|x)
#define COM8_SET_AEC(r,x) (((r)&0xFE)|((x)&1))
#define COM9 0x14 /* AGC gain ceiling */
#define COM9_DEFAULT 0x08
#define COM9_AGC_GAIN_2x 0x00 /* AGC: 2x */
#define COM9_AGC_GAIN_4x 0x01 /* AGC: 4x */
#define COM9_AGC_GAIN_8x 0x02 /* AGC: 8x */
#define COM9_AGC_GAIN_16x 0x03 /* AGC: 16x */
#define COM9_AGC_GAIN_32x 0x04 /* AGC: 32x */
#define COM9_AGC_GAIN_64x 0x05 /* AGC: 64x */
#define COM9_AGC_GAIN_128x 0x06 /* AGC: 128x */
#define COM9_AGC_SET(x) (COM9_DEFAULT|(x<<5))
#define CTRL1_AWB 0x08 /* Enable AWB */
#define VV 0x26
#define VV_AGC_TH_SET(h,l) ((h<<4)|(l&0x0F))
#define REG32 0x32
#define REG32_UXGA 0x36
#define REG32_SVGA 0x09
#define REG32_CIF 0x00
#endif //__REG_REGS_H__

View File

@@ -163,4 +163,10 @@ void Sipeed_ST7789::invertDisplay(boolean invert) {
lcd_set_direction((lcd_dir_t)_screenDir);
}
void Sipeed_ST7789::drawImage(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint16_t* img)
{
configASSERT(img!=nullptr || img!=0);
lcd_draw_picture(x1, y1, width, height, img);
}

View File

@@ -74,6 +74,8 @@ public:
virtual void setRotation(uint8_t r);
virtual void invertDisplay(boolean invert);
void drawImage(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint16_t* img);
private:
SPIClass& _spi;
int8_t _dcxPin;

View File

@@ -215,10 +215,10 @@ void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint
#define SWAP_16(x) ((x >> 8 & 0xff) | (x << 8))
void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr)
void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint16_t *ptr)
{
uint32_t i;
uint16_t *p = (uint16_t *)ptr;
uint16_t *p = ptr;
lcd_set_area(x1, y1, x1 + width - 1, y1 + height - 1);
for (i = 0; i < LCD_MAX_PIXELS; i += 2)
{

View File

@@ -83,7 +83,7 @@ void lcd_set_direction(lcd_dir_t dir);
void lcd_set_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color);
void lcd_draw_string(uint16_t x, uint16_t y, char *str, uint16_t color);
void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr);
void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint16_t *ptr);
void lcd_draw_pic_roi(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t rx, uint16_t ry, uint16_t rw, uint16_t rh, uint32_t *ptr);
void lcd_draw_pic_gray(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint8_t *ptr);
void lcd_draw_pic_grayroi(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t rx, uint16_t ry, uint16_t rw, uint16_t rh, uint8_t *ptr);