WIP: something is working

getting 1/6th of the jpeg frame (at least its now somekind correct)
This commit is contained in:
KubaWis 2025-03-21 19:13:42 +01:00
parent fd0136445b
commit 6766e3a2e6
7 changed files with 885 additions and 111 deletions

180
esp-cam-dump.log Normal file
View File

@ -0,0 +1,180 @@
.pixel_format = PIXFORMAT_JPEG, //YUV422,GRAYSCALE,RGB565,JPEG
.frame_size = FRAMESIZE_240X240, //QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates.
.jpeg_quality = 7, //0-63, for OV series camera sensors, lower number means higher quality
.fb_count = 1,
ov2640_detect
I (379) sccb: SCCB_WRITE addr:0x30, reg:0xff, data:0x01,
I (379) sccb: SCCB_READ addr:0x30, reg:0x0a, data:0x26,
READ PID: I (389) sccb: SCCB_READ addr:0x30, reg:0x0b, data:0x42,
I (399) sccb: SCCB_READ addr:0x30, reg:0x1d, data:0xa2,
I (399) sccb: SCCB_READ addr:0x30, reg:0x1c, data:0x7f,
I (409) camera: Detected OV2640 camera
I (409) camera: Camera PID=0x26 VER=0x42 MIDL=0x7f MIDH=0xa2
I (429) sccb: SCCB_WRITE addr:0x30, reg:0xff, data:0x01,
I (429) sccb: SCCB_WRITE addr:0x30, reg:0x12, data:0x80,
I (439) sccb: SCCB_WRITE addr:0x30, reg:0xff, data:0x00,
I (439) sccb: SCCB_WRITE addr:0x30, reg:0x2c, data:0xff,
I (439) sccb: SCCB_WRITE addr:0x30, reg:0x2e, data:0xdf,
I (449) sccb: SCCB_WRITE addr:0x30, reg:0xff, data:0x01,
I (449) sccb: SCCB_WRITE addr:0x30, reg:0x3c, data:0x32,
I (459) sccb: SCCB_WRITE addr:0x30, reg:0x11, data:0x01,
I (469) sccb: SCCB_WRITE addr:0x30, reg:0x09, data:0x02,
I (469) sccb: SCCB_WRITE addr:0x30, reg:0x04, data:0x28,
I (479) sccb: SCCB_WRITE addr:0x30, reg:0x13, data:0xe5,
I (479) sccb: SCCB_WRITE addr:0x30, reg:0x14, data:0x48,
I (489) sccb: SCCB_WRITE addr:0x30, reg:0x2c, data:0x0c,
I (499) sccb: SCCB_WRITE addr:0x30, reg:0x33, data:0x78,
I (499) sccb: SCCB_WRITE addr:0x30, reg:0x3a, data:0x33,
I (509) sccb: SCCB_WRITE addr:0x30, reg:0x3b, data:0xfb,
I (509) sccb: SCCB_WRITE addr:0x30, reg:0x3e, data:0x00,
I (519) sccb: SCCB_WRITE addr:0x30, reg:0x43, data:0x11,
I (529) sccb: SCCB_WRITE addr:0x30, reg:0x16, data:0x10,
I (529) sccb: SCCB_WRITE addr:0x30, reg:0x39, data:0x92,
I (539) sccb: SCCB_WRITE addr:0x30, reg:0x35, data:0xda,
I (539) sccb: SCCB_WRITE addr:0x30, reg:0x22, data:0x1a,
I (549) sccb: SCCB_WRITE addr:0x30, reg:0x37, data:0xc3,
I (559) sccb: SCCB_WRITE addr:0x30, reg:0x23, data:0x00,
I (559) sccb: SCCB_WRITE addr:0x30, reg:0x34, data:0xc0,
I (569) sccb: SCCB_WRITE addr:0x30, reg:0x06, data:0x88,
I (569) sccb: SCCB_WRITE addr:0x30, reg:0x07, data:0xc0,
I (579) sccb: SCCB_WRITE addr:0x30, reg:0x0d, data:0x87,
I (589) sccb: SCCB_WRITE addr:0x30, reg:0x0e, data:0x41,
I (589) sccb: SCCB_WRITE addr:0x30, reg:0x4c, data:0x00,
I (599) sccb: SCCB_WRITE addr:0x30, reg:0x4a, data:0x81,
I (599) sccb: SCCB_WRITE addr:0x30, reg:0x21, data:0x99,
I (609) sccb: SCCB_WRITE addr:0x30, reg:0x24, data:0x40,
I (619) sccb: SCCB_WRITE addr:0x30, reg:0x25, data:0x38,
I (619) sccb: SCCB_WRITE addr:0x30, reg:0x26, data:0x82,
I (629) sccb: SCCB_WRITE addr:0x30, reg:0x5c, data:0x00,
I (629) sccb: SCCB_WRITE addr:0x30, reg:0x63, data:0x00,
I (639) sccb: SCCB_WRITE addr:0x30, reg:0x61, data:0x70,
I (639) sccb: SCCB_WRITE addr:0x30, reg:0x62, data:0x80,
I (649) sccb: SCCB_WRITE addr:0x30, reg:0x7c, data:0x05,
I (659) sccb: SCCB_WRITE addr:0x30, reg:0x20, data:0x80,
I (659) sccb: SCCB_WRITE addr:0x30, reg:0x28, data:0x30,
I (669) sccb: SCCB_WRITE addr:0x30, reg:0x6c, data:0x00,
I (669) sccb: SCCB_WRITE addr:0x30, reg:0x6d, data:0x80,
I (679) sccb: SCCB_WRITE addr:0x30, reg:0x6e, data:0x00,
I (689) sccb: SCCB_WRITE addr:0x30, reg:0x70, data:0x02,
I (689) sccb: SCCB_WRITE addr:0x30, reg:0x71, data:0x94,
I (699) sccb: SCCB_WRITE addr:0x30, reg:0x73, data:0xc1,
I (699) sccb: SCCB_WRITE addr:0x30, reg:0x3d, data:0x34,
I (709) sccb: SCCB_WRITE addr:0x30, reg:0x5a, data:0x57,
I (719) sccb: SCCB_WRITE addr:0x30, reg:0x4f, data:0xbb,
I (719) sccb: SCCB_WRITE addr:0x30, reg:0x50, data:0x9c,
I (729) sccb: SCCB_WRITE addr:0x30, reg:0x12, data:0x20,
I (729) sccb: SCCB_WRITE addr:0x30, reg:0x17, data:0x11,
I (739) sccb: SCCB_WRITE addr:0x30, reg:0x18, data:0x43,
I (749) sccb: SCCB_WRITE addr:0x30, reg:0x19, data:0x00,
I (749) sccb: SCCB_WRITE addr:0x30, reg:0x1a, data:0x25,
I (759) sccb: SCCB_WRITE addr:0x30, reg:0x32, data:0x89,
I (759) sccb: SCCB_WRITE addr:0x30, reg:0x37, data:0xc0,
I (769) sccb: SCCB_WRITE addr:0x30, reg:0x4f, data:0xca,
I (779) sccb: SCCB_WRITE addr:0x30, reg:0x50, data:0xa8,
I (779) sccb: SCCB_WRITE addr:0x30, reg:0x6d, data:0x00,
I (789) sccb: SCCB_WRITE addr:0x30, reg:0x3d, data:0x38,
I (789) sccb: SCCB_WRITE addr:0x30, reg:0xff, data:0x00,
I (799) sccb: SCCB_WRITE addr:0x30, reg:0xe5, data:0x7f,
I (809) sccb: SCCB_WRITE addr:0x30, reg:0xf9, data:0xc0,
I (809) sccb: SCCB_WRITE addr:0x30, reg:0x41, data:0x24,
I (819) sccb: SCCB_WRITE addr:0x30, reg:0xe0, data:0x14,
I (819) sccb: SCCB_WRITE addr:0x30, reg:0x76, data:0xff,
I (829) sccb: SCCB_WRITE addr:0x30, reg:0x33, data:0xa0,
I (839) sccb: SCCB_WRITE addr:0x30, reg:0x42, data:0x20,
I (839) sccb: SCCB_WRITE addr:0x30, reg:0x43, data:0x18,
I (849) sccb: SCCB_WRITE addr:0x30, reg:0x4c, data:0x00,
I (849) sccb: SCCB_WRITE addr:0x30, reg:0x87, data:0x50,
I (859) sccb: SCCB_WRITE addr:0x30, reg:0x88, data:0x3f,
I (869) sccb: SCCB_WRITE addr:0x30, reg:0xd7, data:0x03,
I (869) sccb: SCCB_WRITE addr:0x30, reg:0xd9, data:0x10,
I (879) sccb: SCCB_WRITE addr:0x30, reg:0xd3, data:0x82,
I (879) sccb: SCCB_WRITE addr:0x30, reg:0xc8, data:0x08,
I (889) sccb: SCCB_WRITE addr:0x30, reg:0xc9, data:0x80,
I (899) sccb: SCCB_WRITE addr:0x30, reg:0x7c, data:0x00,
I (899) sccb: SCCB_WRITE addr:0x30, reg:0x7d, data:0x00,
I (909) sccb: SCCB_WRITE addr:0x30, reg:0x7c, data:0x03,
I (909) sccb: SCCB_WRITE addr:0x30, reg:0x7d, data:0x48,
I (919) sccb: SCCB_WRITE addr:0x30, reg:0x7d, data:0x48,
I (929) sccb: SCCB_WRITE addr:0x30, reg:0x7c, data:0x08,
I (929) sccb: SCCB_WRITE addr:0x30, reg:0x7d, data:0x20,
I (939) sccb: SCCB_WRITE addr:0x30, reg:0x7d, data:0x10,
I (939) sccb: SCCB_WRITE addr:0x30, reg:0x7d, data:0x0e,
I (949) sccb: SCCB_WRITE addr:0x30, reg:0x90, data:0x00,
I (959) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0x0e,
I (959) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0x1a,
I (969) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0x31,
I (969) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0x5a,
I (979) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0x69,
I (989) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0x75,
I (989) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0x7e,
I (999) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0x88,
I (999) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0x8f,
I (1009) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0x96,
I (1019) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0xa3,
I (1019) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0xaf,
I (1029) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0xc4,
I (1029) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0xd7,
I (1039) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0xe8,
I (1049) sccb: SCCB_WRITE addr:0x30, reg:0x91, data:0x20,
I (1049) sccb: SCCB_WRITE addr:0x30, reg:0x92, data:0x00,
I (1059) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x06,
I (1069) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0xe3,
I (1069) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x05,
I (1079) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x05,
I (1079) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x00,
I (1089) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x04,
I (1099) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x00,
I (1099) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x00,
I (1109) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x00,
I (1109) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x00,
I (1119) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x00,
I (1129) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x00,
I (1129) sccb: SCCB_WRITE addr:0x30, reg:0x93, data:0x00,
I (1139) sccb: SCCB_WRITE addr:0x30, reg:0x96, data:0x00,
I (1139) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x08,
I (1149) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x19,
I (1159) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x02,
I (1159) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x0c,
I (1169) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x24,
I (1169) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x30,
I (1179) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x28,
I (1189) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x26,
I (1189) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x02,
I (1199) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x98,
I (1199) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x80,
I (1209) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x00,
I (1219) sccb: SCCB_WRITE addr:0x30, reg:0x97, data:0x00,
I (1219) sccb: SCCB_WRITE addr:0x30, reg:0xa4, data:0x00,
I (1229) sccb: SCCB_WRITE addr:0x30, reg:0xa8, data:0x00,
I (1239) sccb: SCCB_WRITE addr:0x30, reg:0xc5, data:0x11,
I (1239) sccb: SCCB_WRITE addr:0x30, reg:0xc6, data:0x51,
I (1249) sccb: SCCB_WRITE addr:0x30, reg:0xbf, data:0x80,
I (1249) sccb: SCCB_WRITE addr:0x30, reg:0xc7, data:0x10,
I (1259) sccb: SCCB_WRITE addr:0x30, reg:0xb6, data:0x66,
I (1269) sccb: SCCB_WRITE addr:0x30, reg:0xb8, data:0xa5,
I (1269) sccb: SCCB_WRITE addr:0x30, reg:0xb7, data:0x64,
I (1279) sccb: SCCB_WRITE addr:0x30, reg:0xb9, data:0x7c,
I (1279) sccb: SCCB_WRITE addr:0x30, reg:0xb3, data:0xaf,
I (1289) sccb: SCCB_WRITE addr:0x30, reg:0xb4, data:0x97,
I (1299) sccb: SCCB_WRITE addr:0x30, reg:0xb5, data:0xff,
I (1299) sccb: SCCB_WRITE addr:0x30, reg:0xb0, data:0xc5,
I (1309) sccb: SCCB_WRITE addr:0x30, reg:0xb1, data:0x94,
I (1309) sccb: SCCB_WRITE addr:0x30, reg:0xb2, data:0x0f,
I (1319) sccb: SCCB_WRITE addr:0x30, reg:0xc4, data:0x5c,
I (1329) sccb: SCCB_WRITE addr:0x30, reg:0xc3, data:0xfd,
I (1329) sccb: SCCB_WRITE addr:0x30, reg:0x7f, data:0x00,
I (1339) sccb: SCCB_WRITE addr:0x30, reg:0xe5, data:0x1f,
I (1339) sccb: SCCB_WRITE addr:0x30, reg:0xe1, data:0x67,
I (1349) sccb: SCCB_WRITE addr:0x30, reg:0xdd, data:0x7f,
I (1359) sccb: SCCB_WRITE addr:0x30, reg:0xda, data:0x00,
I (1359) sccb: SCCB_WRITE addr:0x30, reg:0xe0, data:0x00,
I (1369) sccb: SCCB_WRITE addr:0x30, reg:0x05, data:0x00,
I (1379) cam_hal: buffer_size: 32768, half_buffer_size: 4096, node_buffer_size: 2048, node_cnt: 16, total_cnt: 2
I (1389) cam_hal: Allocating 11520 Byte frame buffer in PSRAM
E (1389) cam_hal: cam_dma_config(301): frame buffer malloc failed
E (1399) cam_hal: cam_config(390): cam_dma_config failed
E (1399) camera: Camera config failed with error 0xffffffff
E (1409) example:take_picture: Camera Init Failed
I (1419) main_task: Returned from app_main()

View File

@ -22,7 +22,7 @@ camera_config_t left_eye_config = {
.pin_xclk = 3, /*!< GPIO pin for camera XCLK line */ //? in theory could be shared or perhaps ommited?
.pin_sccb_sda = 4, /*!< GPIO pin for camera SDA line */
.pin_sccb_scl = 5, /*!< GPIO pin for camera SCL line */
.pin_data_base = 6, /*!< this pin + 7 consecutive will be used D0-D7 */
.pin_data_base = 6, /*!< this pin + 7 consecutive will be used D0-D7 PCLK HREF */
.pin_vsync = 16, /*!< GPIO pin for camera VSYNC line */
.xclk_freq_hz = 0, /*!< Frequency of XCLK signal, in Hz. */ //! Figure out the highest it can go to
.sccb_ctrl = 0, /* Select i2c controller ctrl: 0 - i2c0, 1 - i2c1, 2 - pio0, 3 - pio1, 4 - pio2 */
@ -35,17 +35,17 @@ int main()
sleep_ms(4000);
//printf("Hello World!");
//printf("construct OV2640!");
OV2640 left_cam = OV2640(left_eye_config);
//printf("begin OV2640!");
left_cam.begin(DMA_IRQ_0);
//left_cam.capture_frame();
//fwrite(left_cam.fb, 1, sizeof(left_cam.fb), stdout);
while (true) {
//printf("Hello, world!\n");
//sleep_ms(1000);
// //printf("Hello, world!\n");
// //sleep_ms(1000);
left_cam.capture_frame();
fwrite(left_cam.fb, 1, sizeof(left_cam.fb), stdout);
memset(&left_cam.fb, 0x00, sizeof(left_cam.fb));
fwrite(&left_cam.fb, 1, sizeof(left_cam.fb), stdout);
// memset(&left_cam.fb, 0x00, sizeof(left_cam.fb));
sleep_ms(1000);
}
}

View File

@ -2,6 +2,7 @@
#include <camera.hpp>
#include "hardware/i2c.h"
#include "pico/stdlib.h"
#include "stdio.h"
#include "src/pio/i2c/pio_i2c.h"
SCCB::SCCB(uint8_t sda_pin, uint8_t scl_pin) {
@ -72,11 +73,26 @@ void SCCB::writeRegister(uint8_t reg, uint8_t value)
buf[1] = value;
if (this->ctrl < 2) {
i2c_write_blocking(this->i2cc, OV2640_ADDR, buf, 2, false);
int ret = i2c_write_blocking(this->i2cc, OV2640_ADDR, buf, 2, false);
if(ret == PICO_ERROR_GENERIC) {
printf("Problem i2c write failed!");
sleep_ms(1000);
}
}else {
//pio_i2c_write_blocking(this->pio, this->sm, OV2640_ADDR, buf, 2);
}
sleep_ms(20);
sleep_ms(30);
}
void SCCB::writeMaskRegister(uint8_t reg, uint8_t offset, uint8_t mask, uint8_t value)
{
uint8_t buf[2];
buf[0] = reg;
buf[1] = value;
uint8_t old_val = this->readRegister(reg);
uint8_t new_value = (old_val & ~(mask << offset)) | ((value & mask) << offset);
this->writeRegister(reg, new_value);
}
void SCCB::writeList(const register_val_t *cfg,

View File

@ -17,6 +17,7 @@ public:
int readRegister(uint8_t reg);
void writeRegister(uint8_t reg, uint8_t value);
void writeMaskRegister(uint8_t reg, uint8_t offset, uint8_t mask, uint8_t value);
void writeList(const register_val_t *cfg, uint16_t len);
private:

View File

@ -13,6 +13,24 @@
#include "src/pio/image/image.pio.h"
static volatile bool frameReady = false; // true at end-of-frame
static volatile bool suspended = true;
static void iCap_vsync_irq(uint gpio, uint32_t events) {
if (!suspended) {
// Clear PIO FIFOs and start DMA transfer
pio_sm_clear_fifos(pio2, 0);
dma_channel_start(0);
}
}
static void iCap_dma_finish_irq() {
frameReady = true;
suspended = true;
//printf("iCap_dma_finish_irq");
dma_hw->ints0 = 1u << 0;
}
// TODO: Stolen from Adafruit repo (Check if correct)
// PIO code in this table is modified at runtime so that PCLK is
@ -33,6 +51,169 @@ static struct pio_program cap_pio_program = {
.origin = -1,
};
register_val_t OV2640_stolem_jpeg_init[] = {
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_SENSOR},
{OV2640_REG1_COM7, OV2640_COM7_SRST},
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP},
{0x2c, 0xff},
{OV2640_REG1_ADDVSH, 0xdf},
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_SENSOR},
{0x3c, 0x32},
{0x11, 0x01},
{0x09, 0x02},
{0x04, 0x28},
{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},
{0x06, 0x88},
{0x07, 0xc0},
{0x0d, 0x87},
{0x0e, 0x41},
{0x4c, 0x00},
{0x4a, 0x81},
{0x21, 0x99},
{0x24, 0x40},
{0x25, 0x38},
{0x26, 0x82},
{0x5c, 0x00},
{0x63, 0x00},
{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},
{0x4f, 0xbb},
{0x50, 0x9c},
{0x12, 0x20},
{0x17, 0x11},
{0x18, 0x43},
{0x19, 0x00},
{0x1a, 0x25},
{0x32, 0x89},
{0x37, 0xc0},
{0x4f, 0xca},
{0x50, 0xa8},
{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, 0x50},
{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},
{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},
{0xc3, 0xfd},
{0x7f, 0x00},
{0xe5, 0x1f},
{0xe1, 0x67},
{0xdd, 0x7f},
{0xda, 0x00},
{0xe0, 0x00},
{0x05, 0x00}
};
register_val_t OV2640_init[] = {
// Ideas from rp2040_ov2640-main repo
// OV2640 camera initialization after reset
@ -284,29 +465,80 @@ register_val_t OV2640_init[] = {
{OV2640_REG0_ZMOH, 0x78}, // OUTH low bits
{OV2640_REG0_ZMHH, 0x00}, // OUTW/H high bits
{OV2640_REG0_R_DVP_SP, 0x02}, // Manual DVP PCLK setting
{OV2640_REG0_RESET, 0x00}}; // Go
// TODO: figure out how to set to JPEG and 260x260
register_val_t OV2640_qqvga[] =
{// Configure OV2640 for QQVGA output
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, // DSP bank select 0
{OV2640_REG0_RESET, OV2640_RESET_DVP},
{OV2640_REG0_HSIZE8, 0x64}, // HSIZE high bits
{OV2640_REG0_VSIZE8, 0x4B}, // VSIZE high bits
{OV2640_REG0_CTRL2, OV2640_CTRL2_DCW | OV2640_CTRL2_SDE |
OV2640_CTRL2_UV_AVG | OV2640_CTRL2_CMX},
{OV2640_REG0_CTRLI, OV2640_CTRLI_LP_DP | 0x12},
{OV2640_REG0_HSIZE, 0xC8}, // H_SIZE low bits
{OV2640_REG0_VSIZE, 0x96}, // V_SIZE low bits
{OV2640_REG0_XOFFL, 0x00}, // OFFSET_X low bits
{OV2640_REG0_YOFFL, 0x00}, // OFFSET_Y low bits
{OV2640_REG0_VHYX, 0x00}, // V/H/Y/X high bits
{OV2640_REG0_TEST, 0x00}, // ?
{OV2640_REG0_ZMOW, 0x28}, // OUTW low bits
{OV2640_REG0_ZMOH, 0x1E}, // OUTH low bits
{OV2640_REG0_ZMHH, 0x00}, // OUTW/H high bits
{OV2640_REG0_R_DVP_SP, 0x08}, // Manual DVP PCLK setting
{OV2640_REG0_RESET, 0x00}
}; // Go
// Stolem from esp32-camera
register_val_t OV2640_jpeg[] = {
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP},
{OV2640_REG0_RESET, OV2640_RESET_JPEG | OV2640_RESET_DVP},
{OV2640_REG0_IMAGE_MODE, OV2640_IMAGE_MODE_JPEG | OV2640_IMAGE_MODE_JPEG_HREF },
{0xD7, 0x03},
{0xE1, 0x77},
{0xE5, 0x1F},
{0xD9, 0x10},
{0xDF, 0x80},
{0x33, 0x80},
{0x3C, 0x10},
{0xEB, 0x30},
{0xDD, 0x7F},
{OV2640_REG0_RESET, 0x00},
{0, 0}
};
register_val_t OV2640_CIF[] = {
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_SENSOR},
{OV2640_REG1_COM7, OV2640_COM7_RES_CIF},
//Set the sensor output window
{OV2640_REG1_COM1, 0x0A},
{OV2640_REG1_REG32, OV2640_REG32_CIF},
{HSTART, 0x11},
{HSTOP, 0x43},
{VSTART, 0x00},
{VSTOP, 0x25},
{CLKRC, 0x00},
{OV2640_REG1_BD50, 0xca},
{OV2640_REG1_BD60, 0xa8},
{0x5a, 0x23},
{0x6d, 0x00},
{0x3d, 0x38},
{0x39, 0x92},
{0x35, 0xda},
{0x22, 0x1a},
{0x37, 0xc3},
{0x23, 0x00},
{OV2640_REG1_ARCOM2, 0xc0},
{0x06, 0x88},
{0x07, 0xc0},
{OV2640_REG1_COM4, 0x87},
{0x0e, 0x41},
{0x4c, 0x00},
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP},
{OV2640_REG0_RESET, OV2640_RESET_DVP},
//Set the sensor resolution (UXGA, SVGA, CIF)
{OV2640_REG0_HSIZE8, 0x32},
{OV2640_REG0_VSIZE8, 0x25},
{OV2640_REG0_SIZEL, 0x00},
//Set the image window size >= output size
{OV2640_REG0_HSIZE, 0x64},
{OV2640_REG0_VSIZE, 0x4a},
{OV2640_REG0_XOFFL, 0x00},
{OV2640_REG0_YOFFL, 0x00},
{OV2640_REG0_VHYX, 0x00},
{OV2640_REG0_TEST, 0x00},
{OV2640_REG0_CTRL2, OV2640_CTRL2_DCW | 0x1D},
{OV2640_REG0_CTRLI, OV2640_CTRLI_LP_DP | 0x00},
{R_DVP_SP, 0x08},
{OV2640_REG0_RESET, 0x00},
{0, 0}
};
register_val_t ov2640_uxga_cif[] = {
{0xff, 0x00},
{0xe0, 0x04},
@ -323,48 +555,31 @@ register_val_t OV2640_qqvga[] =
{0x5a, 0x58},
{0x5b, 0x48},
{0x5c, 0x00},
{0xd3, 0x08},
{0xd3, 0x0f},
{0xe0, 0x00}
};
register_val_t OV2640_rgb[] = {
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, // DSP bank select 0
{OV2640_REG0_RESET, OV2640_RESET_DVP},
{OV2640_REG0_IMAGE_MODE, OV2640_IMAGE_MODE_DVP_RGB565},
{OV2640_REG0_IMAGE_MODE, OV2640_IMAGE_MODE_DVP_RGB565 |
OV2640_IMAGE_MODE_BYTE_SWAP},
{0xD7, 0x03}, // Mystery init values
{0xE1, 0x77}, // seen in other examples
{OV2640_REG0_RESET, 0x00}
}; // Go
register_val_t OV2640_yuv[] = {
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, // DSP bank select 0
{OV2640_REG0_RESET, OV2640_RESET_DVP},
{OV2640_REG0_IMAGE_MODE,
OV2640_IMAGE_MODE_JPEG | OV2640_IMAGE_MODE_JPEG_HREF},
{0xD7, 0x01}, // Mystery init values
{0xE1, 0x67}, // seen in other examples
{OV2640_REG0_RESET, 0x00}
}; // Go
// Stolem from esp32-camera
register_val_t OV2640_jpeg[] = {
{0xFF, 0x0},
{0xE0, 0x10 | 0x04},
{0xDA, 0x10 | 0x02},
{0xD7, 0x03},
{0xE1, 0x77},
{0xE5, 0x1F},
{0xD9, 0x10},
{0xDF, 0x80},
{0x33, 0x80},
{0x3C, 0x10},
{0xEB, 0x30},
{0xDD, 0x7F},
{0xE0, 0x00},
{0, 0}
};
//uint8_t image_buf[160*120*3];
// static const uint8_t special_effects_regs[7 + 1][5] = {
// {0x7C, 0x7D, 0x7C, 0x7D, 0x7D },
// {0x00, 0X00, 0x05, 0X80, 0X80 }, /* no effect */
// {0x00, 0X40, 0x05, 0X80, 0X80 }, /* negative */
// {0x00, 0X18, 0x05, 0X80, 0X80 }, /* black and white */
// {0x00, 0X18, 0x05, 0X40, 0XC0 }, /* reddish */
// {0x00, 0X18, 0x05, 0X40, 0X40 }, /* greenish */
// {0x00, 0X18, 0x05, 0XA0, 0X40 }, /* blue */
// {0x00, 0X18, 0x05, 0X40, 0XA6 }, /* retro */
// };
OV2640::OV2640(camera_config_t config)
{
@ -398,8 +613,8 @@ int OV2640::begin(int dma_irq)
gpio_set_function(this->config.pin_xclk, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(this->config.pin_xclk);
// 8 cycles (0 to 7), 150 MHz / 8 = ~18.71 MHz wrap rate
pwm_set_wrap(slice_num, 7);
pwm_set_gpio_level(this->config.pin_xclk, 4);
pwm_set_wrap(slice_num, 5);
pwm_set_gpio_level(this->config.pin_xclk, 3);
pwm_set_enabled(slice_num, true);
// Init SCCB
@ -419,14 +634,49 @@ int OV2640::begin(int dma_irq)
sleep_ms(300); // Datasheet: tS:RESET = 1 ms
// Init main camera settings
//prtintf("Write list of init\n");
this->sccb.writeList(OV2640_init, sizeof OV2640_init / sizeof OV2640_init[0]);
//prtintf("Write list of qqvga\n");
this->sccb.writeList(ov2640_uxga_cif, sizeof ov2640_uxga_cif / sizeof ov2640_uxga_cif[0]);
//prtintf("Write list of jpeg\n");
this->sccb.writeList(OV2640_jpeg, sizeof OV2640_jpeg / sizeof OV2640_jpeg[0]);
//printf("Stolemjpg init\n");
//this->sccb.writeList(OV2640_stolem_jpeg_init, sizeof(OV2640_stolem_jpeg_init)/sizeof(OV2640_stolem_jpeg_init[0]));
//printf("Stolemjpg init DONE\n");
this->sccb.writeList(OV2640_init, sizeof(OV2640_init)/sizeof(OV2640_init[0]));
this->sccb.writeList(ov2640_uxga_cif, sizeof(ov2640_uxga_cif)/sizeof(ov2640_uxga_cif[0]));
this->sccb.writeList(OV2640_jpeg, sizeof(OV2640_jpeg)/sizeof(OV2640_jpeg[0]));
//this->sccb.writeRegister(0xd3, 0x0f);
// this->set_framesize();
// sleep_ms(10);
// this->sccb.writeList(OV2640_jpeg, sizeof(OV2640_jpeg)/sizeof(OV2640_jpeg[0]));
//this->set_gainceiling(GAINCEILING_2X);
//sleep_ms(10);
//this->set_bpc(false);
//sleep_ms(10);
//this->set_wpc(true);
//sleep_ms(10);
//this->set_lenc(true);
//sleep_ms(10);
this->set_quality(5);
sleep_ms(10);
this->sccb.writeList(OV2640_jpeg, sizeof(OV2640_jpeg)/sizeof(OV2640_jpeg[0]));
this->set_quality(5);
//prtintf("Write list of init\n");
// sleep_ms(10);
// this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP);
sleep_ms(10);
//this->sccb.writeRegister(0xd3, 0x05);
sleep_ms(10);
// // for (int i=0; i<5; i++) {
// // this->sccb.writeRegister(0xff, 0x00);
// // this->sccb.writeRegister(special_effects_regs[0][i], special_effects_regs[3][i]);
// // }
this->sccb.writeRegister(0xff, 0x00);
this->sccb.writeRegister(0xd3, 0x05); // try 0x80 next
this->set_quality(10);
//prtintf("Gpio init\n");
gpio_init(this->config.pin_vsync);
@ -436,6 +686,7 @@ int OV2640::begin(int dma_irq)
{
gpio_init(this->config.pin_data_base + i);
gpio_set_dir(this->config.pin_data_base + i, GPIO_IN);
//gpio_pull_down(this->config.pin_data_base + i);
}
//prtintf("Gpio init done\n");
@ -505,10 +756,69 @@ int OV2640::begin(int dma_irq)
uint offset = pio_add_program(pio2, &image_program);
image_program_init(pio2, 0, offset, this->config.pin_data_base);
//prtintf("IRQ init done\n");
//printf("IRQ init done\n");
//printf("config done");
dma_channel_config c = dma_channel_get_default_config(0);
channel_config_set_transfer_data_size(&c, DMA_SIZE_16);
channel_config_set_read_increment(&c, false);
channel_config_set_write_increment(&c, true);
channel_config_set_bswap(&c, true);
// Set PIO RX as DMA trigger. Input shift register saturates at 16 bits
// (1 pixel), configured in data size above and in PIO setup elsewhere.
channel_config_set_dreq(&c,
pio_get_dreq(pio2, 0, false));
// Set up baseline DMA configuration...it's initially lacking destination
// and count, set later (dma_change()) after resolution is known. DMA
// isn't started until later, and is triggered in the vsync interrupt.
dma_channel_configure(0, &c, &this->fb,
&pio2->rxf[0], sizeof(this->fb), false);
// Set up end-of-DMA interrupt
dma_channel_set_irq0_enabled(0, true);
irq_set_exclusive_handler(DMA_IRQ_0, iCap_dma_finish_irq);
irq_set_enabled(DMA_IRQ_0, true);
// SET UP VSYNC INTERRUPT ------------------------------------------------
gpio_set_irq_enabled_with_callback(this->config.pin_vsync, GPIO_IRQ_EDGE_RISE, true,
&iCap_vsync_irq);
return 0;
}
//! You need to set pixformat after this
void OV2640::set_framesize() {
// uint8_t max_x = 75;
// uint8_t max_y = 74;
// uint8_t w = 60;
// uint8_t h = 60;
// register_val_t win_regs[] = {
// {OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP},
// {OV2640_REG0_HSIZE, 75},
// {OV2640_REG0_VSIZE, 74},
// {OV2640_REG0_XOFFL, 50},
// {OV2640_REG0_YOFFL, 0},
// {OV2640_REG0_VHYX, ((max_y >> 1) & 0X80) | ((0 >> 4) & 0X70) | ((max_x >> 5) & 0X08) | ((50 >> 8) & 0X07)},
// {OV2640_REG0_TEST, (max_x >> 2) & 0X80},
// {OV2640_REG0_ZMOW, (w)&0xFF},
// {OV2640_REG0_ZMOH, (h)&0xFF},
// {OV2640_REG0_ZMHH, ((h>>6)&0x04)|((w>>8)&0x03)},
// {0, 0}
// };
// this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP);
// this->sccb.writeRegister(OV2640_REG0_R_BYPASS, OV2640_R_BYPASS_DSP_BYPASS);
// this->sccb.writeList(OV2640_CIF, sizeof(OV2640_CIF)/sizeof(OV2640_CIF[0]));
// this->sccb.writeList(win_regs, sizeof(win_regs)/sizeof(win_regs[0]));
// this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_SENSOR);
// this->sccb.writeRegister(OV2640_REG1_CLKRC, 0);
// this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP);
// this->sccb.writeRegister(OV2640_REG0_R_DVP_SP, 8);
// this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP);
// this->sccb.writeRegister(OV2640_REG0_R_BYPASS, OV2640_R_BYPASS_DSP_ENABLE);
}
void OV2640::set_quality(int quality) {
if(quality < 0) {
quality = 0;
@ -520,30 +830,58 @@ void OV2640::set_quality(int quality) {
this->sccb.writeRegister(0x44, quality); // set quality
}
void OV2640::set_gainceiling(gainceiling_t gainceiling) {
this->sccb.writeRegister(0xFF, 0x01);
this->sccb.writeMaskRegister(0x14, 5, 7, gainceiling);
}
void OV2640::set_bpc(bool enable) {
this->sccb.writeRegister(0xFF, 0x00);
this->sccb.writeMaskRegister(0x87, 7, 1, enable?1:0);
}
void OV2640::set_wpc(bool enable) {
this->sccb.writeRegister(0xFF, 0x00);
this->sccb.writeMaskRegister(0x87, 6, 1, enable?1:0);
}
void OV2640::set_lenc(bool enable) {
this->sccb.writeRegister(0xFF, 0x00);
this->sccb.writeMaskRegister(0xC3, 1, 1, enable?1:0);
}
void OV2640::capture_frame() {
dma_channel_config c = dma_channel_get_default_config(0);
channel_config_set_read_increment(&c, false);
channel_config_set_write_increment(&c, true);
channel_config_set_dreq(&c, pio_get_dreq(pio2, 0, false));
channel_config_set_transfer_data_size(&c, DMA_SIZE_8);
dma_channel_configure(
0, &c,
&this->fb,
&pio2->rxf[0],
sizeof(this->fb),
false
);
// Wait for vsync rising edge to start frame
////prtintf("pin_vsync) == true\n");
while (gpio_get(this->config.pin_vsync) == true);
////prtintf("pin_vsync) == false\n");
while (gpio_get(this->config.pin_vsync) == false);
////prtintf("after while loops\n");
suspended = false;
while(!frameReady);
return;
// dma_channel_config c = dma_channel_get_default_config(0);
// channel_config_set_read_increment(&c, false);
// channel_config_set_write_increment(&c, true);
// channel_config_set_dreq(&c, pio_get_dreq(pio2, 0, false));
// channel_config_set_transfer_data_size(&c, DMA_SIZE_16);
dma_channel_start(0);
dma_channel_wait_for_finish_blocking(0);
// dma_channel_configure(
// 0, &c,
// &this->fb,
// &pio2->rxf[0],
// sizeof(this->fb),
// false
// );
// // Wait for vsync rising edge to start frame
// ////prtintf("pin_vsync) == true\n");
// while (gpio_get(this->config.pin_vsync) == true);
// ////prtintf("pin_vsync) == false\n");
// while (gpio_get(this->config.pin_vsync) == false);
// ////prtintf("after while loops\n");
// dma_channel_start(0);
// dma_channel_wait_for_finish_blocking(0);
}

View File

@ -20,6 +20,15 @@ typedef struct {
int dma_channel;
} sm_dma_config_t;
typedef enum {
GAINCEILING_2X,
GAINCEILING_4X,
GAINCEILING_8X,
GAINCEILING_16X,
GAINCEILING_32X,
GAINCEILING_64X,
GAINCEILING_128X,
} gainceiling_t;
class OV2640 {
public:
@ -28,9 +37,14 @@ public:
int begin(int dma_irq);
void set_quality(int quality);
void set_gainceiling(gainceiling_t gainceiling);
void set_bpc(bool enable);
void set_wpc(bool enable);
void set_lenc(bool enable);
void set_framesize();
void capture_frame();
uint8_t fb[160*120*3];
uint8_t fb[(352*288)];
camera_config_t config;
private:
@ -44,6 +58,11 @@ private:
#define OV2640_ADDR 0x30
#define HSTART 0x17
#define HSTOP 0x18
#define VSTART 0x19
#define VSTOP 0x1A
#define OV2640_REG_RA_DLMT 0xFF //< Register bank select
#define OV2640_RA_DLMT_DSP 0x00 //< Bank 0 - DSP address
#define OV2640_RA_DLMT_SENSOR 0x01 //< Bank 1 - Sensor address
@ -206,7 +225,7 @@ private:
#define OV2640_COM7_SRST 0x80 //< System reset
#define OV2640_COM7_RES_MASK 0x70 //< Resolution mask
#define OV2640_COM7_RES_UXGA 0x00 //< UXGA (full size) mode
#define OV2640_COM7_RES_CIF 0x10 //< CIF mode
#define OV2640_COM7_RES_CIF 0x20 //< CIF mode
#define OV2640_COM7_RES_SVGA 0x40 //< SVGA mode
#define OV2640_COM7_ZOOM 0x04 //< Zoom mode
#define OV2640_COM7_COLORBAR 0x02 //< Color bar test pattern enable
@ -275,6 +294,7 @@ private:
#define OV2640_REG32_PCLK_DIV4 0xC0 //< PCLK frequency / 4
#define OV2640_REG32_HREFEND_MASK 0x38 //< HREFEND LSBs
#define OV2640_REG32_HREFST_MASK 0x07 //< HREFST LSBs
#define OV2640_REG32_CIF 0x89
#define OV2640_REG1_ARCOM2 0x34 //< ?
#define OV2640_ARCOM2_ZOOM 0x04 //< Zoom window horiz start point
#define OV2640_REG1_REG45 0x45 //< Register 45:
@ -297,3 +317,214 @@ private:
#define OV2640_REG1_REG60 0x60 //< AVGsel[31:24]
#define OV2640_REG1_HISTO_LOW 0x61 //< Histogram low level
#define OV2640_REG1_HISTO_HIGH 0x62 //< Histogram high level
#ifndef __REG_REGS_H__
#define __REG_REGS_H__
/* DSP register bank FF=0x00*/
#define R_BYPASS 0x05
#define QS 0x44
#define CTRLI 0x50
#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 CTRL2 0x86
#define CTRL3 0x87
#define SIZEL 0x8C
#define HSIZE8 0xC0
#define VSIZE8 0xC1
#define CTRL0 0xC2
#define CTRL1 0xC3
#define R_DVP_SP 0xD3
#define IMAGE_MODE 0xDA
#define RESET 0xE0
#define MS_SP 0xF0
#define SS_ID 0xF7
#define SS_CTRL 0xF7
#define MC_BIST 0xF9
#define MC_AL 0xFA
#define MC_AH 0xFB
#define MC_D 0xFC
#define P_CMD 0xFD
#define P_STATUS 0xFE
#define BANK_SEL 0xFF
#define CTRLI_LP_DP 0x80
#define CTRLI_ROUND 0x40
#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_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_BPC_EN 0x80
#define CTRL3_WPC_EN 0x40
#define R_DVP_SP_AUTO_MODE 0x80
#define R_BYPASS_DSP_EN 0x00
#define R_BYPASS_DSP_BYPAS 0x01
#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 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_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
typedef enum {
BANK_DSP, BANK_SENSOR, BANK_MAX
} ov2640_bank_t;
/* Sensor register bank FF=0x01*/
#define GAIN 0x00
#define COM1 0x03
#define REG04 0x04
#define REG08 0x08
#define COM2 0x09
#define REG_PID 0x0A
#define REG_VER 0x0B
#define COM3 0x0C
#define COM4 0x0D
#define AEC 0x10
#define CLKRC 0x11
#define COM7 0x12
#define COM8 0x13
#define COM9 0x14 /* AGC gain ceiling */
#define COM10 0x15
#define HSTART 0x17
#define HSTOP 0x18
#define VSTART 0x19
#define VSTOP 0x1A
#define REG_MIDH 0x1C
#define REG_MIDL 0x1D
#define AEW 0x24
#define AEB 0x25
#define VV 0x26
#define REG2A 0x2A
#define FRARL 0x2B
#define ADDVSL 0x2D
#define ADDVSH 0x2E
#define YAVG 0x2F
#define HSDY 0x30
#define HEDY 0x31
#define REG32 0x32
#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_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 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_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_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 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 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 COM10_HREF_EN 0x80 /* HSYNC changes to HREF */
#define COM10_HSYNC_EN 0x40 /* HREF changes to HSYNC */
#define COM10_PCLK_FREE 0x20 /* PCLK output option: free running PCLK */
#define COM10_PCLK_EDGE 0x10 /* Data is updated at the rising edge of PCLK */
#define COM10_HREF_NEG 0x08 /* HREF negative */
#define COM10_VSYNC_NEG 0x02 /* VSYNC negative */
#define COM10_HSYNC_NEG 0x01 /* HSYNC negative */
#define CTRL1_AWB 0x08 /* Enable AWB */
#define VV_AGC_TH_SET(h,l) ((h<<4)|(l&0x0F))
#define REG32_UXGA 0x36
#define REG32_SVGA 0x09
#define REG32_CIF 0x89
#define CLKRC_2X 0x80
#define CLKRC_2X_UXGA (0x01 | CLKRC_2X)
#define CLKRC_2X_SVGA CLKRC_2X
#define CLKRC_2X_CIF CLKRC_2X
#endif //__REG_REGS_H__

View File

@ -16,6 +16,14 @@
#define image_wrap 3
#define image_pio_version 1
// static const uint16_t image_program_instructions[] = {
// // .wrap_target
// 0x20a9, // 0: wait 1 pin, 9
// 0x20a8, // 1: wait 1 pin, 8
// 0x4008, // 2: in pins, 8
// 0x2028, // 3: wait 0 pin, 8
// // .wrap
// };
static const uint16_t image_program_instructions[] = {
// .wrap_target
0x20a9, // 0: wait 1 pin, 9
@ -46,7 +54,7 @@ void image_program_init(PIO pio, uint sm, uint offset, uint pin_base) {
pio_sm_set_consecutive_pindirs(pio, sm, pin_base, 10, false);
pio_sm_config c = image_program_get_default_config(offset);
sm_config_set_in_pins(&c, pin_base);
sm_config_set_in_shift(&c, false, true, 8);
sm_config_set_in_shift(&c, false, true, 16); // TODO: if something is not working check this i.e revert back to 8 together with dma transfer
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);