Some minor changes

This commit is contained in:
KubaWis 2025-03-27 22:52:08 +01:00
parent fa03a763f1
commit 73e499f215
3 changed files with 66 additions and 72 deletions

View File

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

View File

@ -16,7 +16,7 @@
static volatile bool frameReady = false; // true at end-of-frame static volatile bool frameReady = false; // true at end-of-frame
static volatile bool suspended = true; static volatile bool suspended = true;
void* pointer; static void* pointer;
static void iCap_vsync_irq(uint gpio, uint32_t events) { static void iCap_vsync_irq(uint gpio, uint32_t events) {
if (!suspended) { if (!suspended) {
@ -29,11 +29,9 @@ static void iCap_vsync_irq(uint gpio, uint32_t events) {
static void iCap_dma_finish_irq() { static void iCap_dma_finish_irq() {
frameReady = true; frameReady = true;
suspended = true; suspended = true;
//printf("iCap_dma_finish_irq");
dma_channel_set_write_addr(0, (uint8_t *)(pointer), false); dma_channel_set_write_addr(0, (uint8_t *)(pointer), false);
printf("0x%\n", (uintptr_t)pointer);
dma_hw->ints0 = 1u << 0; dma_hw->ints0 = 1u << 0;
} }
// TODO: Stolen from Adafruit repo (Check if correct) // TODO: Stolen from Adafruit repo (Check if correct)
@ -49,6 +47,7 @@ static uint16_t capture_pio_opcodes[] = {
0b0010000000000000, // WAIT 0 GPIO 0 (mask in PCLK pin before use) 0b0010000000000000, // WAIT 0 GPIO 0 (mask in PCLK pin before use)
}; };
static struct pio_program cap_pio_program = { static struct pio_program cap_pio_program = {
.instructions = capture_pio_opcodes, .instructions = capture_pio_opcodes,
.length = sizeof capture_pio_opcodes / sizeof capture_pio_opcodes[0], .length = sizeof capture_pio_opcodes / sizeof capture_pio_opcodes[0],
@ -56,6 +55,7 @@ static struct pio_program cap_pio_program = {
}; };
// Complete camera init dumped from running esp32 (240x240 JPEG qty: 7)
register_val_t OV2640_stolem_jpeg_init[] = { register_val_t OV2640_stolem_jpeg_init[] = {
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_SENSOR}, {OV2640_REG_RA_DLMT, OV2640_RA_DLMT_SENSOR},
{OV2640_REG1_COM7, OV2640_COM7_SRST}, {OV2640_REG1_COM7, OV2640_COM7_SRST},
@ -218,6 +218,7 @@ register_val_t OV2640_stolem_jpeg_init[] = {
{0x05, 0x00} {0x05, 0x00}
}; };
register_val_t OV2640_init[] = { register_val_t OV2640_init[] = {
// Ideas from rp2040_ov2640-main repo // Ideas from rp2040_ov2640-main repo
// OV2640 camera initialization after reset // OV2640 camera initialization after reset
@ -472,7 +473,6 @@ register_val_t OV2640_init[] = {
{OV2640_REG0_RESET, 0x00} {OV2640_REG0_RESET, 0x00}
}; // Go }; // Go
// Stolem from esp32-camera // Stolem from esp32-camera
register_val_t OV2640_jpeg[] = { register_val_t OV2640_jpeg[] = {
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, {OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP},
@ -567,11 +567,12 @@ register_val_t OV2640_rgb[] = {
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, // DSP bank select 0 {OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, // DSP bank select 0
{OV2640_REG0_RESET, OV2640_RESET_DVP}, {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}, OV2640_IMAGE_MODE_BYTE_SWAP}, // TODO: Check if byteswap is supposed to be enabled?
{0xD7, 0x03}, // Mystery init values {0xD7, 0x03}, // Mystery init values
{0xE1, 0x77}, // seen in other examples {0xE1, 0x77}, // seen in other examples
{OV2640_REG0_RESET, 0x00} {OV2640_REG0_RESET, 0x00}
}; // Go }; // Go
register_val_t OV2640_qqvga[] = { register_val_t OV2640_qqvga[] = {
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, // DSP bank select 0 {OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, // DSP bank select 0
{OV2640_REG0_RESET, OV2640_RESET_DVP}, {OV2640_REG0_RESET, OV2640_RESET_DVP},
@ -610,43 +611,25 @@ OV2640::OV2640(camera_config_t config)
this->config = config; this->config = config;
memset(&this->fb, 0x00, sizeof(this->fb)); memset(&this->fb, 0x00, sizeof(this->fb));
pointer = &this->fb; pointer = &this->fb;
//this->fb = image_buf;
} }
// Pin interrupt on VSYNC calls this to start DMA transfer (unless suspended).
// static void vsync_irq(uint gpio, uint32_t events)
// {
// pio_sm_clear_fifos(pio2, sm);
// dma_channel_start(dma_channel);
// }
// static void dma_finish_irq() // mode 0 - adafruit rgb, 1 - meine jpeg, 2 - stolem jpeg
// { int OV2640::begin(int dma_irq, int mode) // mode is just here to make debbuging easier
// // Channel MUST be reconfigured each time (to reset the dest address).
// dma_channel_set_write_addr(dma_channel,
// (uint8_t *)(image_buf), false);
// dma_hw->ints0 = 1u << dma_channel; // Clear IRQ
// uint32_t data = pio2->rxf[sm];
// fwrite(&data, 1, 32, stdout);
// }
int OV2640::begin(int dma_irq)
{ {
// Initialize peripherals for parallel+I2C camera: // Initialize peripherals for parallel+I2C camera:
// XCLK generation (~18.71 MHz) // XCLK generation (~18.71 MHz)
gpio_set_function(this->config.pin_xclk, GPIO_FUNC_PWM); gpio_set_function(this->config.pin_xclk, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(this->config.pin_xclk); 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_wrap(slice_num, this->config.xclk_div - 1);
pwm_set_gpio_level(this->config.pin_xclk, 4); pwm_set_gpio_level(this->config.xclk_div / 2, 4);
pwm_set_enabled(slice_num, true); pwm_set_enabled(slice_num, true);
// Init SCCB // Init SCCB
//prtintf("Init SCCB\n");
this->sccb = SCCB(this->config.pin_sccb_sda, this->config.pin_sccb_scl); this->sccb = SCCB(this->config.pin_sccb_sda, this->config.pin_sccb_scl);
this->sccb.begin(this->config.sccb_ctrl); this->sccb.begin(this->config.sccb_ctrl);
//prtintf("Inited SCCB\n");
// ENABLE AND/OR RESET CAMERA -------------------------------------------- // ENABLE AND/OR RESET CAMERA --------------------------------------------
// Unsure of camera startup time from beginning of input clock. // Unsure of camera startup time from beginning of input clock.
@ -658,20 +641,30 @@ int OV2640::begin(int dma_irq)
this->sccb.writeRegister(OV2640_REG1_COM7, OV2640_COM7_SRST); // System reset this->sccb.writeRegister(OV2640_REG1_COM7, OV2640_COM7_SRST); // System reset
sleep_ms(300); // Datasheet: tS:RESET = 1 ms sleep_ms(300); // Datasheet: tS:RESET = 1 ms
// Init main camera settings switch(mode) {
//printf("Stolemjpg init\n"); case 0:
//this->sccb.writeList(OV2640_stolem_jpeg_init, sizeof(OV2640_stolem_jpeg_init)/sizeof(OV2640_stolem_jpeg_init[0])); this->sccb.writeList(OV2640_init, sizeof(OV2640_init)/sizeof(OV2640_init[0]));
//printf("Stolemjpg init DONE\n"); this->sccb.writeList(OV2640_CIF, sizeof(OV2640_CIF)/sizeof(OV2640_CIF[0]));
this->sccb.writeList(OV2640_init, sizeof(OV2640_init)/sizeof(OV2640_init[0])); this->sccb.writeList(OV2640_rgb, sizeof(OV2640_rgb)/sizeof(OV2640_qqvga[0]));
this->sccb.writeList(OV2640_qqvga, sizeof(OV2640_qqvga)/sizeof(OV2640_qqvga[0])); break;
this->sccb.writeList(OV2640_rgb, sizeof(OV2640_rgb)/sizeof(OV2640_rgb[0])); case 1:
this->sccb.writeList(OV2640_init, sizeof(OV2640_init)/sizeof(OV2640_init[0]));
this->sccb.writeList(OV2640_CIF, sizeof(OV2640_CIF)/sizeof(OV2640_CIF[0]));
this->sccb.writeList(OV2640_jpeg, sizeof(OV2640_jpeg)/sizeof(OV2640_jpeg[0]));
break;
case 2:
this->sccb.writeList(OV2640_stolem_jpeg_init, sizeof(OV2640_stolem_jpeg_init)/sizeof(OV2640_stolem_jpeg_init[0]));
break;
}
//this->sccb.writeList(OV2640_test_ptrn, sizeof(OV2640_test_ptrn)/sizeof(OV2640_test_ptrn[0]));
//this->sccb.writeList(OV2640_jpeg, sizeof(OV2640_jpeg)/sizeof(OV2640_jpeg[0])); //this->sccb.writeList(OV2640_jpeg, sizeof(OV2640_jpeg)/sizeof(OV2640_jpeg[0]));
//this->sccb.writeRegister(0xd3, 0x0f); //this->sccb.writeRegister(0xd3, 0x0f);
// this->set_framesize(); // this->set_framesize();
// sleep_ms(10); // sleep_ms(10);
// this->sccb.writeList(OV2640_jpeg, sizeof(OV2640_jpeg)/sizeof(OV2640_jpeg[0])); // this->sccb.writeList(OV2640_jpeg, sizeof(OV2640_jpeg)/sizeof(OV2640_jzpeg[0]));
//this->set_gainceiling(GAINCEILING_2X); //this->set_gainceiling(GAINCEILING_2X);
//sleep_ms(10); //sleep_ms(10);
@ -814,35 +807,35 @@ int OV2640::begin(int dma_irq)
//! You need to set pixformat after this //! You need to set pixformat after this
void OV2640::set_framesize() { void OV2640::set_framesize() {
// uint8_t max_x = 75; uint8_t max_x = 75;
// uint8_t max_y = 74; uint8_t max_y = 74;
// uint8_t w = 60; uint8_t w = 60;
// uint8_t h = 60; uint8_t h = 60;
// register_val_t win_regs[] = { register_val_t win_regs[] = {
// {OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, {OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP},
// {OV2640_REG0_HSIZE, 75}, {OV2640_REG0_HSIZE, 75},
// {OV2640_REG0_VSIZE, 74}, {OV2640_REG0_VSIZE, 74},
// {OV2640_REG0_XOFFL, 50}, {OV2640_REG0_XOFFL, 50},
// {OV2640_REG0_YOFFL, 0}, {OV2640_REG0_YOFFL, 0},
// {OV2640_REG0_VHYX, ((max_y >> 1) & 0X80) | ((0 >> 4) & 0X70) | ((max_x >> 5) & 0X08) | ((50 >> 8) & 0X07)}, {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_TEST, (max_x >> 2) & 0X80},
// {OV2640_REG0_ZMOW, (w)&0xFF}, {OV2640_REG0_ZMOW, (w)&0xFF},
// {OV2640_REG0_ZMOH, (h)&0xFF}, {OV2640_REG0_ZMOH, (h)&0xFF},
// {OV2640_REG0_ZMHH, ((h>>6)&0x04)|((w>>8)&0x03)}, {OV2640_REG0_ZMHH, ((h>>6)&0x04)|((w>>8)&0x03)},
// {0, 0} {0, 0}
// }; };
// this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP); 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.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(OV2640_CIF, sizeof(OV2640_CIF)/sizeof(OV2640_CIF[0]));
// this->sccb.writeList(win_regs, sizeof(win_regs)/sizeof(win_regs[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_REG_RA_DLMT, OV2640_RA_DLMT_SENSOR);
// this->sccb.writeRegister(OV2640_REG1_CLKRC, 0); this->sccb.writeRegister(OV2640_REG1_CLKRC, 0);
// this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP); this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP);
// this->sccb.writeRegister(OV2640_REG0_R_DVP_SP, 8); this->sccb.writeRegister(OV2640_REG0_R_DVP_SP, 8);
// this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP); this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP);
// this->sccb.writeRegister(OV2640_REG0_R_BYPASS, OV2640_R_BYPASS_DSP_ENABLE); this->sccb.writeRegister(OV2640_REG0_R_BYPASS, OV2640_R_BYPASS_DSP_ENABLE);
} }
void OV2640::set_quality(int quality) { void OV2640::set_quality(int quality) {
@ -922,3 +915,4 @@ if (flags & 0b1000) { handle_sm_3(); }
*/ */
// TODO: add all of the specific controls like brightness and all of that scheiße // TODO: add all of the specific controls like brightness and all of that scheiße
// THERE ARE MORE COMMENTS THEN ACTUAL CODE AT THIS POINT???

View File

@ -11,7 +11,7 @@ typedef struct {
int pin_sccb_scl; /*!< GPIO pin for camera SCL line */ int pin_sccb_scl; /*!< GPIO pin for camera SCL line */
int pin_data_base; /*!< this pin + 9 consecutive will be used D0-D7 PCLK HREF */ int pin_data_base; /*!< this pin + 9 consecutive will be used D0-D7 PCLK HREF */
int pin_vsync; /*!< GPIO pin for camera VSYNC line */ int pin_vsync; /*!< GPIO pin for camera VSYNC line */
int xclk_freq_hz; /*!< Frequency of XCLK signal, in Hz. */ //! Figure out the highest it can go to int xclk_div; /*!< XCLK divider; 150 / div = XCLK freq. 8 = ~18.71 MHz */ //! Figure out the highest it can go to
uint8_t sccb_ctrl; /* Select i2c controller ctrl: 0 - i2c0, 1 - i2c1, 2 - pio0, 3 - pio1, 4 - pio2 */ uint8_t sccb_ctrl; /* Select i2c controller ctrl: 0 - i2c0, 1 - i2c1, 2 - pio0, 3 - pio1, 4 - pio2 */
} camera_config_t; } camera_config_t;
@ -35,7 +35,7 @@ public:
OV2640(camera_config_t config); OV2640(camera_config_t config);
~OV2640(); ~OV2640();
int begin(int dma_irq); int begin(int dma_irq, int mode);
void set_quality(int quality); void set_quality(int quality);
void set_gainceiling(gainceiling_t gainceiling); void set_gainceiling(gainceiling_t gainceiling);
void set_bpc(bool enable); void set_bpc(bool enable);
@ -44,7 +44,7 @@ public:
void set_framesize(); void set_framesize();
void capture_frame(); void capture_frame();
uint8_t fb[(352*288)]; uint8_t fb[(352*288)]; // TODO: at some point change to a pointer
camera_config_t config; camera_config_t config;
private: private: