Rename SCCB/I2C driver to cambus.

This commit is contained in:
iabdalkader 2017-10-18 23:14:14 +02:00
parent d1a5f72a95
commit 04a14a290f
11 changed files with 295 additions and 321 deletions

View File

@ -128,7 +128,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/, \
framebuffer.o \
array.o \
usbdbg.o \
sccb.o \
cambus.o \
ov9650.o \
ov2640.o \
ov7725.o \

View File

@ -8,7 +8,7 @@ SRCS += $(addprefix , \
framebuffer.c \
array.c \
usbdbg.c \
sccb.c \
cambus.c \
ov9650.c \
ov2640.c \
ov7725.c \

105
src/omv/cambus.c Normal file
View File

@ -0,0 +1,105 @@
/*
* 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.
*
* SCCB (I2C like) driver.
*
*/
#include <stdbool.h>
#include STM32_HAL_H
#include <systick.h>
#include "omv_boardconfig.h"
#include "cambus.h"
#define I2C_FREQUENCY (100000)
#define I2C_TIMEOUT (1000)
static I2C_HandleTypeDef I2CHandle;
int cambus_init()
{
/* Configure I2C */
I2CHandle.Instance = SCCB_I2C;
I2CHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
#if defined(STM32F765xx) || defined(STM32F769xx)
I2CHandle.Init.Timing = 0x40912732; // 100KHz
#else
I2CHandle.Init.ClockSpeed = I2C_FREQUENCY;
I2CHandle.Init.DutyCycle = I2C_DUTYCYCLE_2;
#endif
I2CHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2CHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2CHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
I2CHandle.Init.OwnAddress1 = 0xFE;
I2CHandle.Init.OwnAddress2 = 0xFE;
if (HAL_I2C_Init(&I2CHandle) != HAL_OK) {
/* Initialization Error */
return -1;
}
return 0;
}
int cambus_scan()
{
for (uint8_t addr=0x08; addr<=0x77; addr++) {
__disable_irq();
if (HAL_I2C_IsDeviceReady(&I2CHandle, addr << 1, 10, I2C_TIMEOUT) == HAL_OK) {
__enable_irq();
return (addr << 1);
}
__enable_irq();
}
return 0;
}
int cambus_readb(uint8_t slv_addr, uint8_t reg_addr, uint8_t *reg_data)
{
int ret = 0;
__disable_irq();
if((HAL_I2C_Master_Transmit(&I2CHandle, slv_addr, &reg_addr, 1, I2C_TIMEOUT) != HAL_OK)
|| (HAL_I2C_Master_Receive(&I2CHandle, slv_addr, reg_data, 1, I2C_TIMEOUT) != HAL_OK)) {
ret = -1;
}
__enable_irq();
return ret;
}
int cambus_writeb(uint8_t slv_addr, uint8_t reg_addr, uint8_t reg_data)
{
int ret=0;
uint8_t buf[] = {reg_addr, reg_data};
__disable_irq();
if(HAL_I2C_Master_Transmit(&I2CHandle, slv_addr, buf, 2, I2C_TIMEOUT) != HAL_OK) {
ret = -1;
}
__enable_irq();
return ret;
}
int cambus_readw(uint8_t slv_addr, uint8_t reg_addr, uint16_t *reg_data)
{
int ret=0;
__disable_irq();
if (HAL_I2C_Mem_Read(&I2CHandle, slv_addr, reg_addr,
I2C_MEMADD_SIZE_8BIT, (uint8_t*) reg_data, 2, I2C_TIMEOUT) != HAL_OK) {
ret = -1;
}
__enable_irq();
return ret;
}
int cambus_writew(uint8_t slv_addr, uint8_t reg_addr, uint16_t reg_data)
{
int ret=0;
__disable_irq();
if (HAL_I2C_Mem_Write(&I2CHandle, slv_addr, reg_addr,
I2C_MEMADD_SIZE_8BIT, (uint8_t*) &reg_data, 2, I2C_TIMEOUT) != HAL_OK) {
ret = -1;
}
__enable_irq();
return ret;
}

18
src/omv/cambus.h Normal file
View File

@ -0,0 +1,18 @@
/*
* 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.
*
* Camera bus driver.
*
*/
#ifndef __CAMBUS_H__
#define __CAMBUS_H__
#include <stdint.h>
int cambus_init();
int cambus_scan();
int cambus_readb(uint8_t slv_addr, uint8_t reg_addr, uint8_t *data);
int cambus_writeb(uint8_t slv_addr, uint8_t reg_addr, uint8_t data);
int cambus_readw(uint8_t slv_addr, uint8_t reg_addr, uint16_t *data);
int cambus_writew(uint8_t slv_addr, uint8_t reg_addr, uint16_t data);
#endif // __CAMBUS_H__

View File

@ -10,7 +10,7 @@
#include <stdlib.h>
#include <string.h>
#include STM32_HAL_H
#include "sccb.h"
#include "cambus.h"
#include "ov2640.h"
#include "systick.h"
#include "ov2640_regs.h"
@ -387,8 +387,8 @@ static int reset(sensor_t *sensor)
const uint8_t (*regs)[2];
/* Reset all registers */
SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
SCCB_Write(sensor->slv_addr, COM7, COM7_SRST);
cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
cambus_writeb(sensor->slv_addr, COM7, COM7_SRST);
/* delay n ms */
systick_sleep(10);
@ -397,7 +397,7 @@ static int reset(sensor_t *sensor)
regs = default_regs;
/* Write initial regsiters */
while (regs[i][0]) {
SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]);
cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]);
i++;
}
@ -405,7 +405,7 @@ static int reset(sensor_t *sensor)
regs = svga_regs;
/* Write DSP input regsiters */
while (regs[i][0]) {
SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]);
cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]);
i++;
}
@ -435,7 +435,7 @@ static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
/* Write initial regsiters */
while (regs[i][0]) {
SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]);
cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]);
i++;
}
@ -464,27 +464,27 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
}
/* Disable DSP */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
ret |= SCCB_Write(sensor->slv_addr, R_BYPASS, R_BYPASS_DSP_BYPAS);
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
ret |= cambus_writeb(sensor->slv_addr, R_BYPASS, R_BYPASS_DSP_BYPAS);
/* Write output width */
ret |= SCCB_Write(sensor->slv_addr, ZMOW, (w>>2)&0xFF); /* OUTW[7:0] (real/4) */
ret |= SCCB_Write(sensor->slv_addr, ZMOH, (h>>2)&0xFF); /* OUTH[7:0] (real/4) */
ret |= SCCB_Write(sensor->slv_addr, ZMHH, ((h>>8)&0x04)|((w>>10)&0x03)); /* OUTH[8]/OUTW[9:8] */
ret |= cambus_writeb(sensor->slv_addr, ZMOW, (w>>2)&0xFF); /* OUTW[7:0] (real/4) */
ret |= cambus_writeb(sensor->slv_addr, ZMOH, (h>>2)&0xFF); /* OUTH[7:0] (real/4) */
ret |= cambus_writeb(sensor->slv_addr, ZMHH, ((h>>8)&0x04)|((w>>10)&0x03)); /* OUTH[8]/OUTW[9:8] */
/* Set CLKRC */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
ret |= SCCB_Write(sensor->slv_addr, CLKRC, clkrc);
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
ret |= cambus_writeb(sensor->slv_addr, CLKRC, clkrc);
/* Write DSP input regsiters */
while (regs[i][0]) {
SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]);
cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]);
i++;
}
/* Enable DSP */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
ret |= SCCB_Write(sensor->slv_addr, R_BYPASS, R_BYPASS_DSP_EN);
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
ret |= cambus_writeb(sensor->slv_addr, R_BYPASS, R_BYPASS_DSP_EN);
/* delay n ms */
systick_sleep(30);
@ -507,11 +507,11 @@ static int set_contrast(sensor_t *sensor, int level)
}
/* Switch to DSP register bank */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
/* Write contrast registers */
for (int i=0; i<sizeof(contrast_regs[0])/sizeof(contrast_regs[0][0]); i++) {
ret |= SCCB_Write(sensor->slv_addr, contrast_regs[0][i], contrast_regs[level][i]);
ret |= cambus_writeb(sensor->slv_addr, contrast_regs[0][i], contrast_regs[level][i]);
}
return ret;
@ -527,11 +527,11 @@ static int set_brightness(sensor_t *sensor, int level)
}
/* Switch to DSP register bank */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
/* Write brightness registers */
for (int i=0; i<sizeof(brightness_regs[0])/sizeof(brightness_regs[0][0]); i++) {
ret |= SCCB_Write(sensor->slv_addr, brightness_regs[0][i], brightness_regs[level][i]);
ret |= cambus_writeb(sensor->slv_addr, brightness_regs[0][i], brightness_regs[level][i]);
}
return ret;
@ -547,11 +547,11 @@ static int set_saturation(sensor_t *sensor, int level)
}
/* Switch to DSP register bank */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
/* Write contrast registers */
for (int i=0; i<sizeof(saturation_regs[0])/sizeof(saturation_regs[0][0]); i++) {
ret |= SCCB_Write(sensor->slv_addr, saturation_regs[0][i], saturation_regs[level][i]);
ret |= cambus_writeb(sensor->slv_addr, saturation_regs[0][i], saturation_regs[level][i]);
}
return ret;
@ -562,10 +562,10 @@ static int set_gainceiling(sensor_t *sensor, gainceiling_t gainceiling)
int ret =0;
/* Switch to SENSOR register bank */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
/* Write gain ceiling register */
ret |= SCCB_Write(sensor->slv_addr, COM9, COM9_AGC_SET(gainceiling));
ret |= cambus_writeb(sensor->slv_addr, COM9, COM9_AGC_SET(gainceiling));
return ret;
}
@ -575,24 +575,22 @@ static int set_quality(sensor_t *sensor, int qs)
int ret=0;
/* Switch to DSP register bank */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
/* Write QS register */
ret |= SCCB_Write(sensor->slv_addr, QS, qs);
ret |= cambus_writeb(sensor->slv_addr, QS, qs);
return ret;
}
static int set_colorbar(sensor_t *sensor, int enable)
{
int ret=0;
uint8_t reg;
/* Switch to SENSOR register bank */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
int ret = cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
/* Update COM7 */
reg = SCCB_Read(sensor->slv_addr, COM7);
ret |= cambus_readb(sensor->slv_addr, COM7, &reg);
if (enable) {
reg |= COM7_COLOR_BAR;
@ -600,20 +598,17 @@ static int set_colorbar(sensor_t *sensor, int enable)
reg &= ~COM7_COLOR_BAR;
}
ret |= SCCB_Write(sensor->slv_addr, COM7, reg);
return ret;
return cambus_writeb(sensor->slv_addr, COM7, reg) | ret;
}
static int set_auto_gain(sensor_t *sensor, int enable, int gain)
{
int ret=0;
uint8_t reg;
/* Switch to SENSOR register bank */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
int ret = cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
/* Update COM8 */
reg = SCCB_Read(sensor->slv_addr, COM8);
ret |= cambus_readb(sensor->slv_addr, COM8, &reg);
if (enable) {
reg |= COM8_AGC_EN;
@ -621,20 +616,17 @@ static int set_auto_gain(sensor_t *sensor, int enable, int gain)
reg &= ~COM8_AGC_EN;
}
ret |= SCCB_Write(sensor->slv_addr, COM8, reg);
return ret;
return cambus_writeb(sensor->slv_addr, COM8, reg) | ret;
}
static int set_auto_exposure(sensor_t *sensor, int enable, int exposure)
{
int ret=0;
uint8_t reg;
/* Switch to SENSOR register bank */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
int ret = cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
/* Update COM8 */
reg = SCCB_Read(sensor->slv_addr, COM8);
ret |= cambus_readb(sensor->slv_addr, COM8, &reg);
if (enable) {
reg |= COM8_AEC_EN;
@ -642,20 +634,17 @@ static int set_auto_exposure(sensor_t *sensor, int enable, int exposure)
reg &= ~COM8_AEC_EN;
}
ret |= SCCB_Write(sensor->slv_addr, COM8, reg);
return ret;
return cambus_writeb(sensor->slv_addr, COM8, reg) | ret;
}
static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain)
{
int ret=0;
uint8_t reg;
/* Switch to SENSOR register bank */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
int ret = cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
/* Update CTRL1 */
reg = SCCB_Read(sensor->slv_addr, CTRL1);
ret |= cambus_readb(sensor->slv_addr, CTRL1, &reg);
if (enable) {
reg |= CTRL1_AWB;
@ -663,21 +652,18 @@ static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gai
reg &= ~CTRL1_AWB;
}
ret |= SCCB_Write(sensor->slv_addr, CTRL1, reg);
return ret;
return cambus_writeb(sensor->slv_addr, CTRL1, reg) | ret;
}
static int set_hmirror(sensor_t *sensor, int enable)
{
int ret=0;
uint8_t reg;
/* Switch to SENSOR register bank */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
int ret = cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
/* Update REG04 */
reg = SCCB_Read(sensor->slv_addr, REG04);
ret |= cambus_readb(sensor->slv_addr, REG04, &reg);
if (enable) {
reg |= REG04_HFLIP_IMG;
@ -685,20 +671,17 @@ static int set_hmirror(sensor_t *sensor, int enable)
reg &= ~REG04_HFLIP_IMG;
}
ret |= SCCB_Write(sensor->slv_addr, REG04, reg);
return ret;
return cambus_writeb(sensor->slv_addr, REG04, reg) | ret;
}
static int set_vflip(sensor_t *sensor, int enable)
{
int ret=0;
uint8_t reg;
/* Switch to SENSOR register bank */
ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
int ret = cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);
/* Update REG04 */
reg = SCCB_Read(sensor->slv_addr, REG04);
ret |= cambus_readb(sensor->slv_addr, REG04, &reg);
if (enable) {
reg |= REG04_VFLIP_IMG;
@ -706,8 +689,7 @@ static int set_vflip(sensor_t *sensor, int enable)
reg &= ~REG04_VFLIP_IMG;
}
ret |= SCCB_Write(sensor->slv_addr, REG04, reg);
return ret;
return cambus_writeb(sensor->slv_addr, REG04, reg) | ret;
}
int ov2640_init(sensor_t *sensor)

View File

@ -10,10 +10,10 @@
#include <stdlib.h>
#include <string.h>
#include STM32_HAL_H
#include "sccb.h"
#include "cambus.h"
#include "ov7725.h"
#include "systick.h"
#include "ov7725_regs.h"
#include "systick.h"
#include "omv_boardconfig.h"
static const uint8_t default_regs[][2] = {
@ -157,14 +157,14 @@ static int reset(sensor_t *sensor)
const uint8_t (*regs)[2];
// Reset all registers
SCCB_Write(sensor->slv_addr, COM7, COM7_RESET);
cambus_writeb(sensor->slv_addr, COM7, COM7_RESET);
// Delay 10 ms
systick_sleep(10);
// Write default regsiters
for (i=0, regs = default_regs; regs[i][0]; i++) {
SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]);
cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]);
}
// Delay
@ -175,9 +175,8 @@ static int reset(sensor_t *sensor)
static int sleep(sensor_t *sensor, int enable)
{
int ret=0;
// Read register
uint8_t reg = SCCB_Read(sensor->slv_addr, COM2);
uint8_t reg;
int ret = cambus_readb(sensor->slv_addr, COM2, &reg);
if (enable) {
reg |= COM2_SOFT_SLEEP;
@ -186,43 +185,35 @@ static int sleep(sensor_t *sensor, int enable)
}
// Write back register
ret |= SCCB_Write(sensor->slv_addr, COM2, reg);
return ret;
return cambus_writeb(sensor->slv_addr, COM2, reg) | ret;
}
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
{
int ret=0;
// Read register COM7
uint8_t reg = SCCB_Read(sensor->slv_addr, COM7);
uint8_t reg;
int ret = cambus_readb(sensor->slv_addr, COM7, &reg);
switch (pixformat) {
case PIXFORMAT_RGB565:
reg = COM7_SET_FMT(reg, COM7_FMT_RGB);
ret = SCCB_Write(sensor->slv_addr, DSP_CTRL4, 0);
ret = cambus_writeb(sensor->slv_addr, DSP_CTRL4, 0);
break;
case PIXFORMAT_YUV422:
case PIXFORMAT_GRAYSCALE:
reg = COM7_SET_FMT(reg, COM7_FMT_YUV);
ret = SCCB_Write(sensor->slv_addr, DSP_CTRL4, 0);
ret = cambus_writeb(sensor->slv_addr, DSP_CTRL4, 0);
break;
case PIXFORMAT_BAYER:
reg = COM7_SET_FMT(reg, COM7_FMT_P_BAYER);
ret = SCCB_Write(sensor->slv_addr, DSP_CTRL4, DSP_CTRL4_RAW8);
ret = cambus_writeb(sensor->slv_addr, DSP_CTRL4, DSP_CTRL4_RAW8);
break;
default:
return -1;
}
// Write back register COM7
ret |= SCCB_Write(sensor->slv_addr, COM7, reg);
// Delay
systick_sleep(30);
return ret;
// Write back register
return cambus_writeb(sensor->slv_addr, COM7, reg) | ret;
}
static int set_framesize(sensor_t *sensor, framesize_t framesize)
@ -232,52 +223,51 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
uint16_t h = resolution[framesize][1];
// Write MSBs
ret |= SCCB_Write(sensor->slv_addr, HOUTSIZE, w>>2);
ret |= SCCB_Write(sensor->slv_addr, VOUTSIZE, h>>1);
ret |= cambus_writeb(sensor->slv_addr, HOUTSIZE, w>>2);
ret |= cambus_writeb(sensor->slv_addr, VOUTSIZE, h>>1);
// Write LSBs
ret |= SCCB_Write(sensor->slv_addr, EXHCH, ((w&0x3) | ((h&0x1) << 2)));
ret |= cambus_writeb(sensor->slv_addr, EXHCH, ((w&0x3) | ((h&0x1) << 2)));
if ((w <= 320) && (h <= 240)) {
// Set QVGA Resolution
uint8_t reg = SCCB_Read(sensor->slv_addr, COM7);
uint8_t reg;
int ret = cambus_readb(sensor->slv_addr, COM7, &reg);
reg = COM7_SET_RES(reg, COM7_RES_QVGA);
ret |= SCCB_Write(sensor->slv_addr, COM7, reg);
ret |= cambus_writeb(sensor->slv_addr, COM7, reg);
// Set QVGA Window Size
ret |= SCCB_Write(sensor->slv_addr, HSTART, 0x3F);
ret |= SCCB_Write(sensor->slv_addr, HSIZE, 0x50);
ret |= SCCB_Write(sensor->slv_addr, VSTART, 0x03);
ret |= SCCB_Write(sensor->slv_addr, VSIZE, 0x78);
ret |= SCCB_Write(sensor->slv_addr, HREF, 0x00);
ret |= cambus_writeb(sensor->slv_addr, HSTART, 0x3F);
ret |= cambus_writeb(sensor->slv_addr, HSIZE, 0x50);
ret |= cambus_writeb(sensor->slv_addr, VSTART, 0x03);
ret |= cambus_writeb(sensor->slv_addr, VSIZE, 0x78);
ret |= cambus_writeb(sensor->slv_addr, HREF, 0x00);
// Enable auto-scaling/zooming factors
ret |= SCCB_Write(sensor->slv_addr, DSPAUTO, 0xFF);
ret |= cambus_writeb(sensor->slv_addr, DSPAUTO, 0xFF);
} else {
// Set VGA Resolution
uint8_t reg = SCCB_Read(sensor->slv_addr, COM7);
uint8_t reg;
int ret = cambus_readb(sensor->slv_addr, COM7, &reg);
reg = COM7_SET_RES(reg, COM7_RES_VGA);
ret |= SCCB_Write(sensor->slv_addr, COM7, reg);
ret |= cambus_writeb(sensor->slv_addr, COM7, reg);
// Set VGA Window Size
ret |= SCCB_Write(sensor->slv_addr, HSTART, 0x23);
ret |= SCCB_Write(sensor->slv_addr, HSIZE, 0xA0);
ret |= SCCB_Write(sensor->slv_addr, VSTART, 0x07);
ret |= SCCB_Write(sensor->slv_addr, VSIZE, 0xF0);
ret |= SCCB_Write(sensor->slv_addr, HREF, 0x00);
ret |= cambus_writeb(sensor->slv_addr, HSTART, 0x23);
ret |= cambus_writeb(sensor->slv_addr, HSIZE, 0xA0);
ret |= cambus_writeb(sensor->slv_addr, VSTART, 0x07);
ret |= cambus_writeb(sensor->slv_addr, VSIZE, 0xF0);
ret |= cambus_writeb(sensor->slv_addr, HREF, 0x00);
// Disable auto-scaling/zooming factors
ret |= SCCB_Write(sensor->slv_addr, DSPAUTO, 0xF3);
ret |= cambus_writeb(sensor->slv_addr, DSPAUTO, 0xF3);
// Clear auto-scaling/zooming factors
ret |= SCCB_Write(sensor->slv_addr, SCAL0, 0x00);
ret |= SCCB_Write(sensor->slv_addr, SCAL1, 0x00);
ret |= SCCB_Write(sensor->slv_addr, SCAL2, 0x00);
ret |= cambus_writeb(sensor->slv_addr, SCAL0, 0x00);
ret |= cambus_writeb(sensor->slv_addr, SCAL1, 0x00);
ret |= cambus_writeb(sensor->slv_addr, SCAL2, 0x00);
}
// Delay
systick_sleep(30);
return ret;
}
@ -288,28 +278,24 @@ static int set_framerate(sensor_t *sensor, framerate_t framerate)
static int set_contrast(sensor_t *sensor, int level)
{
int ret=0;
level += (NUM_CONTRAST_LEVELS / 2);
if (level < 0 || level >= NUM_CONTRAST_LEVELS) {
return -1;
}
ret |= SCCB_Write(sensor->slv_addr, CONTRAST, contrast_regs[level][0]);
return ret;
return cambus_writeb(sensor->slv_addr, CONTRAST, contrast_regs[level][0]);
}
static int set_brightness(sensor_t *sensor, int level)
{
int ret=0;
level += (NUM_BRIGHTNESS_LEVELS / 2);
if (level < 0 || level >= NUM_BRIGHTNESS_LEVELS) {
return -1;
}
ret |= SCCB_Write(sensor->slv_addr, BRIGHTNESS, brightness_regs[level][0]);
ret |= SCCB_Write(sensor->slv_addr, SIGN_BIT, brightness_regs[level][1]);
ret |= cambus_writeb(sensor->slv_addr, BRIGHTNESS, brightness_regs[level][0]);
ret |= cambus_writeb(sensor->slv_addr, SIGN_BIT, brightness_regs[level][1]);
return ret;
}
@ -322,60 +308,48 @@ static int set_saturation(sensor_t *sensor, int level)
return -1;
}
ret |= SCCB_Write(sensor->slv_addr, USAT, saturation_regs[level][0]);
ret |= SCCB_Write(sensor->slv_addr, VSAT, saturation_regs[level][1]);
ret |= cambus_writeb(sensor->slv_addr, USAT, saturation_regs[level][0]);
ret |= cambus_writeb(sensor->slv_addr, VSAT, saturation_regs[level][1]);
return ret;
}
static int set_gainceiling(sensor_t *sensor, gainceiling_t gainceiling)
{
// Read register COM9
uint8_t reg = SCCB_Read(sensor->slv_addr, COM9);
uint8_t reg;
int ret = cambus_readb(sensor->slv_addr, COM9, &reg);
// Set gain ceiling
reg = COM9_SET_AGC(reg, gainceiling);
// Write back register COM9
return SCCB_Write(sensor->slv_addr, COM9, reg);
return cambus_writeb(sensor->slv_addr, COM9, reg) | ret;
}
static int set_colorbar(sensor_t *sensor, int enable)
{
int ret=0;
uint8_t reg;
// Read reg COM3
reg = SCCB_Read(sensor->slv_addr, COM3);
int ret = cambus_readb(sensor->slv_addr, COM3, &reg);
// Enable colorbar test pattern output
reg = COM3_SET_CBAR(reg, enable);
// Write back COM3
ret |= SCCB_Write(sensor->slv_addr, COM3, reg);
ret |= cambus_writeb(sensor->slv_addr, COM3, reg);
// Read reg DSP_CTRL3
reg = SCCB_Read(sensor->slv_addr, DSP_CTRL3);
// Enable DSP colorbar output
ret |= cambus_readb(sensor->slv_addr, DSP_CTRL3, &reg);
reg = DSP_CTRL3_SET_CBAR(reg, enable);
// Write back DSP_CTRL3
ret |= SCCB_Write(sensor->slv_addr, DSP_CTRL3, reg);
return ret;
return cambus_writeb(sensor->slv_addr, DSP_CTRL3, reg) | ret;
}
static int set_auto_gain(sensor_t *sensor, int enable, int gain)
{
int ret=0;
// Read register COM8
uint8_t reg = SCCB_Read(sensor->slv_addr, COM8);
uint8_t reg;
int ret = cambus_readb(sensor->slv_addr, COM8, &reg);
// Set AGC on/off
reg = COM8_SET_AGC(reg, enable);
// Write back register COM8
ret |= SCCB_Write(sensor->slv_addr, COM8, reg);
ret |= cambus_writeb(sensor->slv_addr, COM8, reg);
if (enable == 0 && gain >= 0) {
// Set value manually.
ret |= SCCB_Write(sensor->slv_addr, GAIN, gain);
ret |= cambus_writeb(sensor->slv_addr, GAIN, gain);
}
return ret;
@ -383,44 +357,35 @@ static int set_auto_gain(sensor_t *sensor, int enable, int gain)
static int set_auto_exposure(sensor_t *sensor, int enable, int exposure)
{
int ret=0;
// Read register COM8
uint8_t reg = SCCB_Read(sensor->slv_addr, COM8);
uint8_t reg;
int ret = cambus_readb(sensor->slv_addr, COM8, &reg);
// Set AEC on/off
reg = COM8_SET_AEC(reg, enable);
// Write back register COM8
ret |= SCCB_Write(sensor->slv_addr, COM8, reg);
ret |= cambus_writeb(sensor->slv_addr, COM8, reg);
if (enable == 0 && exposure >= 0) {
// Set value manually.
ret |= SCCB_Write(sensor->slv_addr, AEC, (exposure&0xFF));
ret |= SCCB_Write(sensor->slv_addr, AECH, ((exposure>>8)&0xFF));
ret |= cambus_writeb(sensor->slv_addr, AEC, (exposure&0xFF));
ret |= cambus_writeb(sensor->slv_addr, AECH, ((exposure>>8)&0xFF));
}
return ret;
}
static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain)
{
int ret=0;
// Read register COM8
uint8_t reg = SCCB_Read(sensor->slv_addr, COM8);
uint8_t reg;
int ret = cambus_readb(sensor->slv_addr, COM8, &reg);
// Set AWB on/off
reg = COM8_SET_AWB(reg, enable);
// Write back register COM8
ret |= SCCB_Write(sensor->slv_addr, COM8, reg);
ret |= cambus_writeb(sensor->slv_addr, COM8, reg);
if (enable == 0 && r_gain >= 0 && g_gain >=0 && b_gain >=0) {
// Set value manually.
ret |= SCCB_Write(sensor->slv_addr, RED, r_gain);
ret |= SCCB_Write(sensor->slv_addr, GREEN, g_gain);
ret |= SCCB_Write(sensor->slv_addr, BLUE, b_gain);
ret |= cambus_writeb(sensor->slv_addr, RED, r_gain);
ret |= cambus_writeb(sensor->slv_addr, GREEN, g_gain);
ret |= cambus_writeb(sensor->slv_addr, BLUE, b_gain);
}
return ret;
@ -428,26 +393,24 @@ static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gai
static int set_hmirror(sensor_t *sensor, int enable)
{
// Read register COM3
uint8_t reg = SCCB_Read(sensor->slv_addr, COM3);
uint8_t reg;
int ret = cambus_readb(sensor->slv_addr, COM3, &reg);
// Set mirror on/off
reg = COM3_SET_MIRROR(reg, enable);
// Write back register COM3
return SCCB_Write(sensor->slv_addr, COM3, reg);
return cambus_writeb(sensor->slv_addr, COM3, reg) | ret;
}
static int set_vflip(sensor_t *sensor, int enable)
{
// Read register COM3
uint8_t reg = SCCB_Read(sensor->slv_addr, COM3);
uint8_t reg;
int ret = cambus_readb(sensor->slv_addr, COM3, &reg);
// Set mirror on/off
reg = COM3_SET_FLIP(reg, enable);
// Write back register COM3
return SCCB_Write(sensor->slv_addr, COM3, reg);
return cambus_writeb(sensor->slv_addr, COM3, reg) | ret;
}
static int set_special_effect(sensor_t *sensor, sde_t sde)
@ -456,12 +419,12 @@ static int set_special_effect(sensor_t *sensor, sde_t sde)
switch (sde) {
case SDE_NEGATIVE:
ret |= SCCB_Write(sensor->slv_addr, SDE, 0x46);
ret |= cambus_writeb(sensor->slv_addr, SDE, 0x46);
break;
case SDE_NORMAL:
ret |= SCCB_Write(sensor->slv_addr, SDE, 0x06);
ret |= SCCB_Write(sensor->slv_addr, UFIX, 0x80);
ret |= SCCB_Write(sensor->slv_addr, UFIX, 0x80);
ret |= cambus_writeb(sensor->slv_addr, SDE, 0x06);
ret |= cambus_writeb(sensor->slv_addr, UFIX, 0x80);
ret |= cambus_writeb(sensor->slv_addr, UFIX, 0x80);
break;
default:
return -1;
@ -474,9 +437,9 @@ static int set_lens_correction(sensor_t *sensor, int enable, int radi, int coef)
{
int ret=0;
ret |= SCCB_Write(sensor->slv_addr, LC_CTR, (enable&0x01));
ret |= SCCB_Write(sensor->slv_addr, LC_RADI, radi);
ret |= SCCB_Write(sensor->slv_addr, LC_COEF, coef);
ret |= cambus_writeb(sensor->slv_addr, LC_CTR, (enable&0x01));
ret |= cambus_writeb(sensor->slv_addr, LC_RADI, radi);
ret |= cambus_writeb(sensor->slv_addr, LC_COEF, coef);
return ret;
}

View File

@ -10,7 +10,7 @@
#include <stdlib.h>
#include <string.h>
#include STM32_HAL_H
#include "sccb.h"
#include "cambus.h"
#include "ov9650.h"
#include "systick.h"
#include "ov9650_regs.h"
@ -202,14 +202,14 @@ static int reset(sensor_t *sensor)
const uint8_t (*regs)[2]=default_regs;
/* Reset all registers */
SCCB_Write(sensor->slv_addr, REG_COM7, 0x80);
cambus_writeb(sensor->slv_addr, REG_COM7, 0x80);
/* delay n ms */
systick_sleep(10);
/* Write initial regsiters */
while (regs[i][0]) {
SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]);
cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]);
i++;
}
@ -223,7 +223,7 @@ static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
uint8_t com7=0; /* framesize/RGB */
/* read pixel format reg */
com7 = SCCB_Read(sensor->slv_addr, REG_COM7);
cambus_readb(sensor->slv_addr, REG_COM7, &com7);
switch (pixformat) {
case PIXFORMAT_RGB565:
@ -243,11 +243,11 @@ static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
}
/* Set pixel format */
SCCB_Write(sensor->slv_addr, REG_COM7, com7);
cambus_writeb(sensor->slv_addr, REG_COM7, com7);
/* Write pixel format registers */
while (regs[i][0]) {
SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]);
cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]);
i++;
}
@ -260,7 +260,8 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
uint8_t com1=0; /* Skip option */
/* read COM7 RGB bit */
com7 = (SCCB_Read(sensor->slv_addr, REG_COM7) & REG_COM7_RGB);
cambus_readb(sensor->slv_addr, REG_COM7, &com7);
com7 &= REG_COM7_RGB;
switch (framesize) {
case FRAMESIZE_QQCIF:
@ -279,8 +280,8 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
}
/* write the frame size registers */
SCCB_Write(sensor->slv_addr, REG_COM1, com1);
SCCB_Write(sensor->slv_addr, REG_COM7, com7);
cambus_writeb(sensor->slv_addr, REG_COM1, com1);
cambus_writeb(sensor->slv_addr, REG_COM7, com7);
return 0;
}
@ -288,7 +289,7 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
static int set_framerate(sensor_t *sensor, framerate_t framerate)
{
/* Write framerate register */
SCCB_Write(sensor->slv_addr, REG_CLKRC, framerate);
cambus_writeb(sensor->slv_addr, REG_CLKRC, framerate);
return 0;
}
@ -313,7 +314,7 @@ static int set_brightness(sensor_t *sensor, int level)
}
for (i=0; i<3; i++) {
SCCB_Write(sensor->slv_addr, regs[0][i], regs[level][i]);
cambus_writeb(sensor->slv_addr, regs[0][i], regs[level][i]);
}
return 0;
@ -322,16 +323,16 @@ static int set_brightness(sensor_t *sensor, int level)
//static int set_exposure(sensor_t *sensor, int exposure)
//{
// uint8_t val;
// val = SCCB_Read(sensor->slv_addr, REG_COM1);
// val = cambus_readb(sensor->slv_addr, REG_COM1);
// /* exposure [1:0] */
// SCCB_Write(sensor->slv_addr, REG_COM1, val | (exposure&0x03));
// cambus_writeb(sensor->slv_addr, REG_COM1, val | (exposure&0x03));
// /* exposure [9:2] */
// SCCB_Write(sensor->slv_addr, REG_AECH, ((exposure>>2)&0xFF));
// cambus_writeb(sensor->slv_addr, REG_AECH, ((exposure>>2)&0xFF));
// /* exposure [15:10] */
// SCCB_Write(sensor->slv_addr, REG_AECHM, ((exposure>>10)&0x3F));
// cambus_writeb(sensor->slv_addr, REG_AECHM, ((exposure>>10)&0x3F));
// return 0;
//}
@ -339,16 +340,16 @@ static int set_brightness(sensor_t *sensor, int level)
static int set_gainceiling(sensor_t *sensor, gainceiling_t gainceiling)
{
/* Write gain ceiling register */
SCCB_Write(sensor->slv_addr, REG_COM9, (gainceiling<<4));
cambus_writeb(sensor->slv_addr, REG_COM9, (gainceiling<<4));
return 0;
}
static int set_auto_gain(sensor_t *sensor, int enable, int gain)
{
uint8_t val;
val = SCCB_Read(sensor->slv_addr, REG_COM8);
cambus_readb(sensor->slv_addr, REG_COM8, &val);
SCCB_Write(sensor->slv_addr, REG_COM8,
cambus_writeb(sensor->slv_addr, REG_COM8,
enable ? (val | REG_COM8_AGC) : (val & ~REG_COM8_AGC));
return 0;
@ -357,9 +358,9 @@ static int set_auto_gain(sensor_t *sensor, int enable, int gain)
static int set_auto_exposure(sensor_t *sensor, int enable, int exposure)
{
uint8_t val;
val = SCCB_Read(sensor->slv_addr, REG_COM8);
cambus_readb(sensor->slv_addr, REG_COM8, &val);
SCCB_Write(sensor->slv_addr, REG_COM8,
cambus_writeb(sensor->slv_addr, REG_COM8,
enable ? (val | REG_COM8_AEC) : (val & ~REG_COM8_AEC));
return 0;
@ -368,9 +369,9 @@ static int set_auto_exposure(sensor_t *sensor, int enable, int exposure)
static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain)
{
uint8_t val;
val = SCCB_Read(sensor->slv_addr, REG_COM8);
cambus_readb(sensor->slv_addr, REG_COM8, &val);
SCCB_Write(sensor->slv_addr, REG_COM8,
cambus_writeb(sensor->slv_addr, REG_COM8,
enable ? (val | REG_COM8_AWB) : (val & ~REG_COM8_AWB));
return 0;
@ -379,9 +380,9 @@ static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gai
static int set_hmirror(sensor_t *sensor, int enable)
{
uint8_t val;
val = SCCB_Read(sensor->slv_addr, REG_MVFP);
cambus_readb(sensor->slv_addr, REG_MVFP, &val);
SCCB_Write(sensor->slv_addr, REG_MVFP,
cambus_writeb(sensor->slv_addr, REG_MVFP,
enable ? (val | REG_MVFP_HMIRROR) : (val & ~REG_MVFP_HMIRROR));
return 0;
@ -390,9 +391,9 @@ static int set_hmirror(sensor_t *sensor, int enable)
static int set_vflip(sensor_t *sensor, int enable)
{
uint8_t val;
val = SCCB_Read(sensor->slv_addr, REG_MVFP);
cambus_readb(sensor->slv_addr, REG_MVFP, &val);
SCCB_Write(sensor->slv_addr, REG_MVFP,
cambus_writeb(sensor->slv_addr, REG_MVFP,
enable ? (val | REG_MVFP_VFLIP) : (val & ~REG_MVFP_VFLIP));
return 0;

View File

@ -8,7 +8,6 @@
*/
#include "mp.h"
#include "pin.h"
#include "sccb.h"
#include "sensor.h"
#include "imlib.h"
#include "xalloc.h"

View File

@ -1,82 +0,0 @@
/*
* 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.
*
* SCCB (I2C like) driver.
*
*/
#include <stdbool.h>
#include STM32_HAL_H
#include <systick.h>
#include "omv_boardconfig.h"
#include "sccb.h"
#define SCCB_FREQ (100000) // We don't need fast I2C. 100KHz is fine here.
#define TIMEOUT (1000) /* Can't be sure when I2C routines return. Interrupts
while polling hardware may result in unknown delays. */
static I2C_HandleTypeDef I2CHandle;
int SCCB_Init()
{
/* Configure I2C */
I2CHandle.Instance = SCCB_I2C;
I2CHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
#if defined(STM32F765xx) || defined(STM32F769xx)
I2CHandle.Init.Timing = 0x40912732; // 100KHz
#else
I2CHandle.Init.ClockSpeed = SCCB_FREQ;
I2CHandle.Init.DutyCycle = I2C_DUTYCYCLE_2;
#endif
I2CHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2CHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2CHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
I2CHandle.Init.OwnAddress1 = 0xFE;
I2CHandle.Init.OwnAddress2 = 0xFE;
if (HAL_I2C_Init(&I2CHandle) != HAL_OK) {
/* Initialization Error */
return -1;
}
return 0;
}
uint8_t SCCB_Probe()
{
uint8_t reg = 0;
for (int i=0; i<127; i++) {
__disable_irq();
if (HAL_I2C_Master_Transmit(&I2CHandle, i, &reg, 1, TIMEOUT) == HAL_OK) {
__enable_irq();
return i;
}
__enable_irq();
systick_sleep(1);
}
return 0;
}
uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg)
{
uint8_t data=0;
__disable_irq();
if((HAL_I2C_Master_Transmit(&I2CHandle, slv_addr, &reg, 1, TIMEOUT) != HAL_OK)
|| (HAL_I2C_Master_Receive(&I2CHandle, slv_addr, &data, 1, TIMEOUT) != HAL_OK)) {
data=0xFF;
}
__enable_irq();
return data;
}
uint8_t SCCB_Write(uint8_t slv_addr, uint8_t reg, uint8_t data)
{
uint8_t ret=0;
uint8_t buf[] = {reg, data};
__disable_irq();
if(HAL_I2C_Master_Transmit(&I2CHandle, slv_addr, buf, 2, TIMEOUT) != HAL_OK) {
ret=0xFF;
}
__enable_irq();
return ret;
}

View File

@ -1,16 +0,0 @@
/*
* 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.
*
* SCCB (I2C like) driver.
*
*/
#ifndef __SCCB_H__
#define __SCCB_H__
#include <stdint.h>
int SCCB_Init();
uint8_t SCCB_Probe();
uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg);
uint8_t SCCB_Write(uint8_t slv_addr, uint8_t reg, uint8_t data);
#endif // __SCCB_H__

View File

@ -10,7 +10,7 @@
#include <string.h>
#include "mp.h"
#include "irq.h"
#include "sccb.h"
#include "cambus.h"
#include "ov9650.h"
#include "ov2640.h"
#include "ov7725.h"
@ -201,8 +201,8 @@ int sensor_init()
DCMI_PWDN_LOW();
systick_sleep(10);
/* Initialize the SCCB interface */
SCCB_Init();
/* Initialize the camera bus */
cambus_init();
systick_sleep(10);
// Configure the sensor external clock (XCLK) to XCLK_FREQ.
@ -239,7 +239,7 @@ int sensor_init()
memset(&sensor, 0, sizeof(sensor_t));
/* Some sensors have different reset polarities, and we can't know which sensor
is connected before initializing SCCB and probing the sensor, which in turn
is connected before initializing cambus and probing the sensor, which in turn
requires pulling the sensor out of the reset state. So we try to probe the
sensor with both polarities to determine line state. */
sensor.reset_pol = ACTIVE_HIGH;
@ -252,7 +252,7 @@ int sensor_init()
systick_sleep(10);
/* Probe the sensor */
sensor.slv_addr = SCCB_Probe();
sensor.slv_addr = cambus_scan();
if (sensor.slv_addr == 0) {
/* Sensor has been held in reset,
so the reset line is active low */
@ -263,7 +263,7 @@ int sensor_init()
systick_sleep(10);
/* Probe again to set the slave addr */
sensor.slv_addr = SCCB_Probe();
sensor.slv_addr = cambus_scan();
if (sensor.slv_addr == 0) {
// Probe failed
return -2;
@ -271,10 +271,10 @@ int sensor_init()
}
/* Read the sensor information */
sensor.id.PID = SCCB_Read(sensor.slv_addr, REG_PID);
sensor.id.VER = SCCB_Read(sensor.slv_addr, REG_VER);
sensor.id.MIDL = SCCB_Read(sensor.slv_addr, REG_MIDL);
sensor.id.MIDH = SCCB_Read(sensor.slv_addr, REG_MIDH);
cambus_readb(sensor.slv_addr, REG_PID, &sensor.id.PID);
cambus_readb(sensor.slv_addr, REG_VER, &sensor.id.VER);
cambus_readb(sensor.slv_addr, REG_MIDL, &sensor.id.MIDL);
cambus_readb(sensor.slv_addr, REG_MIDH, &sensor.id.MIDH);
/* Call the sensor-specific init function */
switch (sensor.id.PID) {
@ -288,8 +288,8 @@ int sensor_init()
ov7725_init(&sensor);
break;
default:
/* Sensor not supported */
return -3;
// Sensor is not supported.
return -1;
}
/* Configure the DCMI DMA Stream */
@ -355,14 +355,18 @@ int sensor_sleep(int enable)
return 0;
}
int sensor_read_reg(uint8_t reg)
int sensor_read_reg(uint8_t reg_addr)
{
return SCCB_Read(sensor.slv_addr, reg);
uint8_t reg_data;
if (cambus_readb(sensor.slv_addr, reg_addr, &reg_data) != 0) {
return -1;
}
return reg_data;
}
int sensor_write_reg(uint8_t reg, uint8_t val)
int sensor_write_reg(uint8_t reg_addr, uint8_t reg_data)
{
return SCCB_Write(sensor.slv_addr, reg, val);
return cambus_writeb(sensor.slv_addr, reg_addr, reg_data);
}
int sensor_set_pixformat(pixformat_t pixformat)