mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #2440 from openmv/add_pag7936_driver
sensors: Add PAG7936 sensor driver.
This commit is contained in:
commit
c2945a08ec
@ -46,6 +46,7 @@ SRCS += $(addprefix sensors/, \
|
||||
gc2145.c \
|
||||
genx320.c \
|
||||
pag7920.c \
|
||||
pag7936.c \
|
||||
paj6100.c \
|
||||
frogeye2020.c \
|
||||
)
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#define GENX320_SLV_ADDR (0x78)
|
||||
#define FROGEYE2020_SLV_ADDR (0x6E)
|
||||
#define PAG7920_SLV_ADDR (0x80)
|
||||
#define PAG7936_SLV_ADDR (0x80)
|
||||
|
||||
// Chip ID Registers
|
||||
#define OV5640_CHIP_ID (0x300A)
|
||||
@ -33,7 +34,7 @@
|
||||
#define HIMAX_CHIP_ID (0x0001)
|
||||
#define GC_CHIP_ID (0xF0)
|
||||
#define GENX320_CHIP_ID (0x0014)
|
||||
#define PIXART_CHIP_ID (0x00)
|
||||
#define PIXART_CHIP_ID (0x0000)
|
||||
|
||||
// Chip ID Values
|
||||
#define OV2640_ID (0x26)
|
||||
@ -62,6 +63,7 @@
|
||||
#define GENX320_ID_ES (0x30501C01)
|
||||
#define GENX320_ID_MP (0xB0602003)
|
||||
#define PAG7920_ID (0x7920)
|
||||
#define PAG7936_ID (0x7936)
|
||||
#define PAJ6100_ID (0x6100)
|
||||
#define FROGEYE2020_ID (0x2020)
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "hm01b0.h"
|
||||
#include "hm0360.h"
|
||||
#include "pag7920.h"
|
||||
#include "pag7936.h"
|
||||
#include "paj6100.h"
|
||||
#include "frogeye2020.h"
|
||||
#include "gc2145.h"
|
||||
@ -255,10 +256,17 @@ static int sensor_detect() {
|
||||
|
||||
#if (OMV_PAG7920_ENABLE == 1)
|
||||
case PAG7920_SLV_ADDR:
|
||||
omv_i2c_readw(&sensor.i2c_bus, slv_addr, ON_CHIP_ID, (uint16_t *) &sensor.chip_id);
|
||||
sensor.chip_id = (sensor.chip_id << 8) | (sensor.chip_id >> 8);
|
||||
omv_i2c_readw2(&sensor.i2c_bus, slv_addr, PIXART_CHIP_ID, (uint16_t *) &sensor.chip_id);
|
||||
sensor.chip_id = ((sensor.chip_id << 8) | (sensor.chip_id >> 8)) & 0xFFFF;
|
||||
return slv_addr;
|
||||
#endif // (OMV_PAG7920_ENABLE == 1)
|
||||
|
||||
#if (OMV_PAG7936_ENABLE == 1)
|
||||
case PAG7936_SLV_ADDR:
|
||||
omv_i2c_readw2(&sensor.i2c_bus, slv_addr, PIXART_CHIP_ID, (uint16_t *) &sensor.chip_id);
|
||||
sensor.chip_id = ((sensor.chip_id << 8) | (sensor.chip_id >> 8)) & 0xFFFF;
|
||||
return slv_addr;
|
||||
#endif // (OMV_PAG7936_ENABLE == 1)
|
||||
}
|
||||
}
|
||||
|
||||
@ -472,6 +480,15 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed) {
|
||||
break;
|
||||
#endif // (OMV_PAG7920_ENABLE == 1)
|
||||
|
||||
#if (OMV_PAG7936_ENABLE == 1)
|
||||
case PAG7936_ID:
|
||||
if (sensor_set_xclk_frequency(OMV_PAG7936_XCLK_FREQ) != 0) {
|
||||
return SENSOR_ERROR_TIM_INIT_FAILED;
|
||||
}
|
||||
init_ret = pag7936_init(&sensor);
|
||||
break;
|
||||
#endif // (OMV_PAG7936_ENABLE == 1)
|
||||
|
||||
#if (OMV_PAJ6100_ENABLE == 1)
|
||||
case PAJ6100_ID:
|
||||
if (sensor_set_xclk_frequency(OMV_PAJ6100_XCLK_FREQ) != 0) {
|
||||
|
||||
437
src/omv/sensors/pag7936.c
Normal file
437
src/omv/sensors/pag7936.c
Normal file
@ -0,0 +1,437 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 OpenMV, LLC.
|
||||
*
|
||||
* 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. Any redistribution, use, or modification in source or binary form
|
||||
* is done solely for personal benefit and not for any commercial
|
||||
* purpose or for monetary gain. For commercial licensing options,
|
||||
* please contact openmv@openmv.io
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "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 LICENSOR OR COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* PixArt PAG7936 driver.
|
||||
*/
|
||||
#include "omv_boardconfig.h"
|
||||
#if (OMV_PAG7936_ENABLE == 1)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "omv_i2c.h"
|
||||
#include "sensor.h"
|
||||
#include "pag7936.h"
|
||||
#include "py/mphal.h"
|
||||
|
||||
#define FRAME_TIME_20_16 (0x004E)
|
||||
#define FRAME_TIME_15_8 (0x004D)
|
||||
#define FRAME_TIME_7_0 (0x004C)
|
||||
#define AGC_H (0x1424)
|
||||
#define AGC_L (0x1423)
|
||||
#define AE_EXPO_MANUAL_17_16 (0x1427)
|
||||
#define AE_EXPO_MANUAL_15_8 (0x1426)
|
||||
#define AE_EXPO_MANUAL_7_0 (0x1425)
|
||||
#define SENSOR_UPDATE (0x00EB)
|
||||
#define INTERFACE_POLARITY (0x0EAF)
|
||||
#define SENSOR_OPMODE (0x0008)
|
||||
#define SENSOR_TRIGGER_FRAMENUM (0x002E)
|
||||
#define SENSOR_TRIGGER_EN (0x002F)
|
||||
#define SENSOR_TG_EN (0x0030)
|
||||
#define SENSOR_TRIGGER_MODE (0x0031)
|
||||
#define SENSOR_SOFTWARE_TRIGGER (0x00EA)
|
||||
#define ISP_WOI_EN (0x0E10)
|
||||
#define ISP_WOI_HSIZE_L (0x0E11)
|
||||
#define ISP_WOI_HSIZE_H (0x0E12)
|
||||
#define ISP_WOI_VSIZE_L (0x0E13)
|
||||
#define ISP_WOI_VSIZE_H (0x0E14)
|
||||
#define ISP_WOI_HOFFSET_L (0x0E15)
|
||||
#define ISP_WOI_HOFFSET_H (0x0E16)
|
||||
#define ISP_WOI_VOFFSET_L (0x0E17)
|
||||
#define ISP_WOI_VOFFSET_H (0x0E18)
|
||||
#define TG_MONO_SENSOR (0x01BF)
|
||||
#define TG_FLIP (0x01CE)
|
||||
#define TG_FLIP_SET_VFLIP(r, x) ((r & 0xFB) | ((x & 1) << 2))
|
||||
#define TG_FLIP_SET_HFLIP(r, x) ((r & 0xF7) | ((x & 1) << 3))
|
||||
#define AVERAGE_MODE (0x01C0)
|
||||
#define ROW_AVERAGE_MODE (0x0166)
|
||||
#define COL_AVERAGE_MODE (0x016F)
|
||||
#define HSIZE_L (0x01C6)
|
||||
#define HSIZE_H (0x01C7)
|
||||
#define VSIZE_L (0x01C8)
|
||||
#define VSIZE_H (0x01C9)
|
||||
#define WOI_HSIZE_L (0x0221)
|
||||
#define WOI_HSIZE_H (0x0222)
|
||||
#define WOI_VSIZE_L (0x0223)
|
||||
#define WOI_VSIZE_H (0x0224)
|
||||
#define WOI_HSTART_L (0x0225)
|
||||
#define WOI_HSTART_H (0x0226)
|
||||
#define WOI_VSTART_L (0x0227)
|
||||
#define WOI_VSTART_H (0x0228)
|
||||
|
||||
#define RGB_STAT_B_VS (0x04C9)
|
||||
#define RGB_STAT_GB_VS (0x04CD)
|
||||
#define RGB_STAT_R_VS (0x04D1)
|
||||
#define RGB_STAT_GR_VS (0x04D5)
|
||||
|
||||
#define FT_CLK (1000000)
|
||||
#define FPS_MAX (120) // by sensor setting!!
|
||||
|
||||
#define FMAX_720P_120_LINEAR (1041) // by sensor setting!!
|
||||
#define LT_T_RATIO (1000000 / FPS_MAX / FMAX_720P_120_LINEAR / 8) // around ~1.0 with current setting
|
||||
#define ConvertL2T(line) (line * LT_T_RATIO) // 1-Line time = 8usec = 1T, return T
|
||||
#define ConvertT2L(t) ((t + (LT_T_RATIO / 2)) / LT_T_RATIO) // 1-Line time = 8usec = 1T, return Lines
|
||||
|
||||
#define PAG7936_MIN_INT (ConvertT2L(10)) // ExpLine min vlaue
|
||||
#define PAG7936_MAX_INT ((FMAX_720P_120_LINEAR - 11)) // ExpLine max vlaue
|
||||
#define PAG7936_MIN_AGAIN (1472) // AGain min value, unit is 1/1024x
|
||||
#define PAG7936_MAX_AGAIN (16384) // AGain max value, unit is 1/1024x
|
||||
|
||||
#if OMV_PAG7936_MIPI
|
||||
#define PAG7936_WIDTH_ALIGN (8)
|
||||
#else
|
||||
#define PAG7936_WIDTH_ALIGN (4)
|
||||
#endif
|
||||
|
||||
static const uint16_t default_regs[][2] = {
|
||||
{ 0x010C, 0x23 },
|
||||
{ 0x010D, 0x05 },
|
||||
{ 0x007B, 0x8C },
|
||||
{ 0x007C, 0x8C },
|
||||
{ 0x007D, 0x8C },
|
||||
{ 0x007E, 0x8C },
|
||||
{ 0x007F, 0x8C },
|
||||
{ 0x0EAF, 0x31 }, // Interface polarity (Not default)
|
||||
{ 0x004C, 0x1A },
|
||||
{ 0x004D, 0x41 },
|
||||
{ 0x004E, 0x00 },
|
||||
{ 0x004F, 0x00 },
|
||||
{ 0x110A, 0x00 },
|
||||
{ 0x0905, 0x60 },
|
||||
{ 0x0978, 0x01 },
|
||||
{ 0x0979, 0x64 },
|
||||
{ 0x097C, 0xE6 },
|
||||
{ 0x097D, 0x00 },
|
||||
{ 0x097E, 0x08 },
|
||||
{ 0x097F, 0x02 },
|
||||
{ 0x0985, 0x10 },
|
||||
{ 0x098B, 0x90 },
|
||||
{ 0x098E, 0x06 },
|
||||
{ 0x0810, 0x01 },
|
||||
{ 0x0850, 0x00 },
|
||||
{ 0x094A, 0x43 },
|
||||
{ 0x09A0, 0x08 },
|
||||
{ 0x0724, 0x10 },
|
||||
{ 0x0110, 0x1B },
|
||||
{ 0x0111, 0x03 },
|
||||
{ 0x0114, 0xF4 },
|
||||
{ 0x0186, 0x40 },
|
||||
{ 0x0188, 0x14 },
|
||||
{ 0x02A5, 0xEF },
|
||||
{ 0x016B, 0x5D },
|
||||
{ 0x0634, 0xE0 },
|
||||
{ 0x0635, 0x01 },
|
||||
{ 0x0646, 0x12 },
|
||||
{ 0x0647, 0x02 },
|
||||
{ 0x064E, 0x3A },
|
||||
{ 0x064F, 0x02 },
|
||||
{ 0x0654, 0x30 },
|
||||
{ 0x0655, 0x02 },
|
||||
{ 0x065A, 0x3F },
|
||||
{ 0x065B, 0x02 },
|
||||
{ 0x066A, 0x7B },
|
||||
{ 0x066B, 0x02 },
|
||||
{ 0x066E, 0xD2 },
|
||||
{ 0x0683, 0x9E },
|
||||
{ 0x0684, 0x02 },
|
||||
{ 0x0687, 0xF5 },
|
||||
{ 0x06B5, 0xA8 },
|
||||
{ 0x06B6, 0x02 },
|
||||
{ 0x06B9, 0xFF },
|
||||
{ 0x06C3, 0xA3 },
|
||||
{ 0x06C4, 0x02 },
|
||||
{ 0x06C7, 0xFA },
|
||||
{ 0x06D1, 0x12 },
|
||||
{ 0x06D2, 0x02 },
|
||||
{ 0x06D7, 0x76 },
|
||||
{ 0x06D8, 0x02 },
|
||||
{ 0x06DB, 0xCD },
|
||||
{ 0x0A1A, 0x20 },
|
||||
{ 0x0A32, 0x2A },
|
||||
{ 0x0A33, 0x2A },
|
||||
{ 0x0A34, 0x0D },
|
||||
{ 0x0A35, 0x0D },
|
||||
{ 0x0E10, 0x01 },
|
||||
{ 0x0E11, 0x00 },
|
||||
{ 0x0E12, 0x05 },
|
||||
{ 0x0E13, 0x20 },
|
||||
{ 0x0E14, 0x03 },
|
||||
{ 0x0E15, 0x10 },
|
||||
{ 0x0E16, 0x00 },
|
||||
{ 0x0E17, 0x10 },
|
||||
{ 0x0E18, 0x00 },
|
||||
{ 0x00EB, 0x80 },
|
||||
{ 0x000B, 0x02 },
|
||||
{ 0x0030, 0x01 },
|
||||
{ 0x0008, 0x83 },
|
||||
{ 0x0000, 0x00 },
|
||||
};
|
||||
|
||||
static const uint16_t qvga_regs[][2] = {
|
||||
{ TG_MONO_SENSOR, 0x00 },
|
||||
{ AVERAGE_MODE, 0x02 },
|
||||
{ ROW_AVERAGE_MODE, 0x00 },
|
||||
{ COL_AVERAGE_MODE, 0x00 },
|
||||
{ ISP_WOI_EN, 0x00 },
|
||||
{ HSIZE_L, 0x44 },
|
||||
{ HSIZE_H, 0x01 },
|
||||
{ VSIZE_L, 0xCC },
|
||||
{ VSIZE_H, 0x00 },
|
||||
{ WOI_HSIZE_L, 0x40 },
|
||||
{ WOI_HSIZE_H, 0x01 },
|
||||
{ WOI_VSIZE_L, 0xC8 },
|
||||
{ WOI_VSIZE_H, 0x00 },
|
||||
{ WOI_HSTART_L, 0x02 },
|
||||
{ WOI_HSTART_H, 0x00 },
|
||||
{ WOI_VSTART_L, 0x02 },
|
||||
{ WOI_VSTART_H, 0x00 },
|
||||
{ SENSOR_UPDATE, 0x80 },
|
||||
{ 0x0000, 0x00 },
|
||||
};
|
||||
|
||||
static const uint16_t vga_regs[][2] = {
|
||||
{ TG_MONO_SENSOR, 0x00 },
|
||||
{ AVERAGE_MODE, 0x01 },
|
||||
{ ROW_AVERAGE_MODE, 0x00 },
|
||||
{ COL_AVERAGE_MODE, 0x00 },
|
||||
{ ISP_WOI_EN, 0x00 },
|
||||
{ HSIZE_L, 0x88 },
|
||||
{ HSIZE_H, 0x02 },
|
||||
{ VSIZE_L, 0x98 },
|
||||
{ VSIZE_H, 0x01 },
|
||||
{ WOI_HSIZE_L, 0x80 },
|
||||
{ WOI_HSIZE_H, 0x02 },
|
||||
{ WOI_VSIZE_L, 0x90 },
|
||||
{ WOI_VSIZE_H, 0x01 },
|
||||
{ WOI_HSTART_L, 0x04 },
|
||||
{ WOI_HSTART_H, 0x00 },
|
||||
{ WOI_VSTART_L, 0x04 },
|
||||
{ WOI_VSTART_H, 0x00 },
|
||||
{ SENSOR_UPDATE, 0x80 },
|
||||
{ 0x0000, 0x00 },
|
||||
};
|
||||
|
||||
static const uint16_t hd_regs[][2] = {
|
||||
{ TG_MONO_SENSOR, 0x00 },
|
||||
{ AVERAGE_MODE, 0x00 },
|
||||
{ ROW_AVERAGE_MODE, 0x00 },
|
||||
{ COL_AVERAGE_MODE, 0x00 },
|
||||
{ ISP_WOI_EN, 0x01 },
|
||||
{ ISP_WOI_HSIZE_L, 0x00 },
|
||||
{ ISP_WOI_HSIZE_H, 0x05 },
|
||||
{ ISP_WOI_VSIZE_L, 0x20 },
|
||||
{ ISP_WOI_VSIZE_H, 0x03 },
|
||||
{ ISP_WOI_HOFFSET_L, 0x10 },
|
||||
{ ISP_WOI_HOFFSET_H, 0x00 },
|
||||
{ ISP_WOI_VOFFSET_L, 0x10 },
|
||||
{ ISP_WOI_VOFFSET_H, 0x00 },
|
||||
{ HSIZE_L, 0x10 },
|
||||
{ HSIZE_H, 0x05 },
|
||||
{ VSIZE_L, 0x30 },
|
||||
{ VSIZE_H, 0x03 },
|
||||
{ WOI_HSIZE_L, 0x10 },
|
||||
{ WOI_HSIZE_H, 0x05 },
|
||||
{ WOI_VSIZE_L, 0x30 },
|
||||
{ WOI_VSIZE_H, 0x03 },
|
||||
{ WOI_HSTART_L, 0x00 },
|
||||
{ WOI_HSTART_H, 0x00 },
|
||||
{ WOI_VSTART_L, 0x00 },
|
||||
{ WOI_VSTART_H, 0x00 },
|
||||
{ SENSOR_UPDATE, 0x80 },
|
||||
{ 0x0000, 0x00 },
|
||||
};
|
||||
|
||||
static int reset(sensor_t *sensor) {
|
||||
int ret = 0;
|
||||
// Write default registers
|
||||
for (int i = 0; default_regs[i][0] && ret == 0; i++) {
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, default_regs[i][0], default_regs[i][1]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sleep(sensor_t *sensor, int enable) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_reg(sensor_t *sensor, uint16_t reg) {
|
||||
uint8_t reg_data;
|
||||
if (omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, reg, ®_data) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return reg_data;
|
||||
}
|
||||
|
||||
static int write_reg(sensor_t *sensor, uint16_t reg, uint16_t reg_data) {
|
||||
return omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, reg, reg_data);
|
||||
}
|
||||
|
||||
static int read_reg_seq(sensor_t *sensor, uint16_t addr, size_t size, uint8_t *buf) {
|
||||
int ret = 0;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, addr + i, &buf[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat) {
|
||||
switch (pixformat) {
|
||||
case PIXFORMAT_RGB565:
|
||||
case PIXFORMAT_BAYER:
|
||||
case PIXFORMAT_GRAYSCALE:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int set_framesize(sensor_t *sensor, framesize_t framesize) {
|
||||
int ret = 0;
|
||||
const uint16_t(*regs)[2];
|
||||
|
||||
switch (framesize) {
|
||||
case FRAMESIZE_HD:
|
||||
regs = hd_regs;
|
||||
break;
|
||||
case FRAMESIZE_VGA:
|
||||
regs = vga_regs;
|
||||
break;
|
||||
case FRAMESIZE_QVGA:
|
||||
regs = qvga_regs;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; regs[i][0] && ret == 0; i++) {
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, regs[i][0], regs[i][1]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_framerate(sensor_t *sensor, int framerate) {
|
||||
int ret = 0;
|
||||
int32_t frame_time = FT_CLK / framerate;
|
||||
int32_t integ_time = IM_CLAMP((frame_time - 11), PAG7936_MIN_INT, PAG7936_MAX_INT);
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, FRAME_TIME_20_16, ((frame_time >> 16) & 0x1F));
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, FRAME_TIME_15_8, ((frame_time >> 8) & 0xFF));
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, FRAME_TIME_7_0, (frame_time & 0xFF));
|
||||
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AE_EXPO_MANUAL_17_16, ((integ_time >> 16) & 0x03));
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AE_EXPO_MANUAL_15_8, ((integ_time >> 8) & 0xFF));
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AE_EXPO_MANUAL_7_0, (integ_time & 0xFF));
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, SENSOR_UPDATE, 0x80);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_colorbar(sensor_t *sensor, int enable) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_hmirror(sensor_t *sensor, int enable) {
|
||||
uint8_t reg;
|
||||
int ret = omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, TG_FLIP, ®);
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, TG_FLIP, TG_FLIP_SET_HFLIP(reg, enable));
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, SENSOR_UPDATE, 0x80);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_vflip(sensor_t *sensor, int enable) {
|
||||
uint8_t reg;
|
||||
int ret = omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, TG_FLIP, ®);
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, TG_FLIP, TG_FLIP_SET_VFLIP(reg, enable));
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, SENSOR_UPDATE, 0x80);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ioctl(sensor_t *sensor, int request, va_list ap) {
|
||||
int ret = 0;
|
||||
|
||||
(void) read_reg_seq;
|
||||
|
||||
switch (request) {
|
||||
case IOCTL_GET_RGB_STATS: {
|
||||
uint32_t rgb_stats[4];
|
||||
uint8_t buf[] = {(RGB_STAT_B_VS >> 8), RGB_STAT_B_VS & 0xFF };
|
||||
ret |= omv_i2c_write_bytes(&sensor->i2c_bus, sensor->slv_addr, buf, 2, OMV_I2C_XFER_NO_STOP);
|
||||
ret |= omv_i2c_read_bytes(&sensor->i2c_bus, sensor->slv_addr, (uint8_t *) rgb_stats, sizeof(rgb_stats), 0);
|
||||
|
||||
*va_arg(ap, uint32_t *) = rgb_stats[2];
|
||||
*va_arg(ap, uint32_t *) = rgb_stats[1];
|
||||
*va_arg(ap, uint32_t *) = rgb_stats[3];
|
||||
*va_arg(ap, uint32_t *) = rgb_stats[0];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pag7936_init(sensor_t *sensor) {
|
||||
// Initialize sensor flags.
|
||||
sensor->vsync_pol = 0;
|
||||
sensor->hsync_pol = 0;
|
||||
sensor->pixck_pol = 1;
|
||||
sensor->mono_bpp = 1;
|
||||
sensor->raw_output = 1;
|
||||
sensor->cfa_format = SUBFORMAT_ID_BGGR;
|
||||
|
||||
// Initialize sensor ops.
|
||||
sensor->reset = reset;
|
||||
sensor->sleep = sleep;
|
||||
sensor->ioctl = ioctl;
|
||||
sensor->read_reg = read_reg;
|
||||
sensor->write_reg = write_reg;
|
||||
sensor->set_pixformat = set_pixformat;
|
||||
sensor->set_framesize = set_framesize;
|
||||
sensor->set_framerate = set_framerate;
|
||||
sensor->set_colorbar = set_colorbar;
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
|
||||
// Override standard resolutions
|
||||
resolution[FRAMESIZE_HD][0] = 1280;
|
||||
resolution[FRAMESIZE_HD][1] = 800;
|
||||
|
||||
resolution[FRAMESIZE_VGA][0] = 640;
|
||||
resolution[FRAMESIZE_VGA][1] = 400;
|
||||
|
||||
resolution[FRAMESIZE_QVGA][0] = 320;
|
||||
resolution[FRAMESIZE_QVGA][1] = 200;
|
||||
return 0;
|
||||
}
|
||||
#endif // (OMV_PAG7936_ENABLE == 1)
|
||||
37
src/omv/sensors/pag7936.h
Normal file
37
src/omv/sensors/pag7936.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 OpenMV, LLC.
|
||||
*
|
||||
* 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. Any redistribution, use, or modification in source or binary form
|
||||
* is done solely for personal benefit and not for any commercial
|
||||
* purpose or for monetary gain. For commercial licensing options,
|
||||
* please contact openmv@openmv.io
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "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 LICENSOR OR COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* PixArt PAG7936 driver.
|
||||
*/
|
||||
#ifndef __PAG7936_H__
|
||||
#define __PAG7936_H__
|
||||
#define OMV_PAG7936_XCLK_FREQ (24000000)
|
||||
int pag7936_init(sensor_t *sensor);
|
||||
#endif // __PAG7936_H__
|
||||
Loading…
Reference in New Issue
Block a user