-
Notifications
You must be signed in to change notification settings - Fork 7.7k
-
Hi,
I am trying to integrate OV5640 camera into ESP32-S3 using GDMA and LCD_CAM peripheral
without any success.
Is it possible to do this in Arduino or I have to use idf ?.
Regards.
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment 5 replies
-
There is an example here you need to make sure that you have undefined the proper board also here and comment the line above that.
Beta Was this translation helpful? Give feedback.
All reactions
-
Thanks but I intend to develop the code from scratch.
My first try is the following but the dma_callback is not executed.
I appreciate any help, thanks.
`
// "ESP32S3 Dev Module" 2.0.9
#include <esp_rom_gpio.h>
#include <driver/periph_ctrl.h>
#include <esp_private/gdma.h>
#include <hal/dma_types.h>
#include <soc/lcd_cam_struct.h>
#define dmabuf_camrx_len 1470 // DMA camera RX buffer size
gdma_channel_handle_t dma_camrx_chan; // CAM RX DMA channel
uint8_t dmabuf_camrx[dmabuf_camrx_len]; // DMA RX camera buffer
dma_descriptor_t desc; // DMA RX camera descriptor
#define pclk_pin 13
#define xclk_pin 21
#define href_pin 46
#define d2_pin 40
#define d3_pin 39
#define d4_pin 38
#define d5_pin 37
#define d6_pin 36
#define d7_pin 5
#define d8_pin 45
#define d9_pin 47
// End of DMA transfer callback
static IRAM_ATTR bool dma_callback(gdma_channel_handle_t dma_camrx_chan, gdma_event_data_t *event_data, void *user_data) {
Serial.println("End of DMA transfer");
return true;
}
void setup() {
Serial.begin(115200);
// LCD_CAM peripheral enable and reset
periph_module_enable(PERIPH_LCD_CAM_MODULE);
periph_module_reset(PERIPH_LCD_CAM_MODULE);
////////// Reset CAM bus
LCD_CAM.cam_ctrl1.cam_reset = 1;
// CAM module registers configuration
LCD_CAM.cam_ctrl.cam_clk_sel = 1; // XTAL_CLK source (40MHz)
LCD_CAM.cam_ctrl.cam_clkm_div_num = 2; // CAM_CLK_IDX = 20MHz
LCD_CAM.cam_ctrl.cam_clkm_div_b = 0;
LCD_CAM.cam_ctrl.cam_clkm_div_a = 0;
LCD_CAM.cam_ctrl1.cam_vh_de_mode_en = 1;
LCD_CAM.cam_ctrl.cam_update = 1;
// Route CAM signals to GPIO pins
const struct {
uint32_t pin;
uint8_t signal;
} mux[] = {
{ d2_pin, CAM_DATA_IN0_IDX }, { d3_pin, CAM_DATA_IN1_IDX }, { d4_pin, CAM_DATA_IN2_IDX },
{ d5_pin, CAM_DATA_IN3_IDX }, { d6_pin, CAM_DATA_IN4_IDX }, { d7_pin, CAM_DATA_IN5_IDX },
{ d8_pin, CAM_DATA_IN6_IDX }, { d9_pin, CAM_DATA_IN7_IDX }, { pclk_pin, CAM_PCLK_IDX },
{ href_pin, CAM_H_ENABLE_IDX },
{ GPIO_MATRIX_CONST_ONE_INPUT, CAM_H_SYNC_IDX }, { GPIO_MATRIX_CONST_ONE_INPUT, CAM_V_SYNC_IDX }
};
for (int i = 0; i < 12; i++) {
if (mux[i].pin != GPIO_MATRIX_CONST_ONE_INPUT) {
esp_rom_gpio_pad_select_gpio(mux[i].pin);
}
esp_rom_gpio_connect_in_signal(mux[i].pin, mux[i].signal, false);
}
esp_rom_gpio_pad_select_gpio(xclk_pin);
esp_rom_gpio_pad_set_drv(xclk_pin, 3);
esp_rom_gpio_connect_out_signal(xclk_pin, CAM_CLK_IDX, false, false);
// GDMA descriptor
desc.dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA;
desc.dw0.suc_eof = 1; // Last descriptor
desc.dw0.size = dmabuf_camrx_len;
desc.buffer = dmabuf_camrx;
desc.next = NULL;
// Allocate DMA channel and connect it to the CAM peripheral
gdma_channel_alloc_config_t dma_camrx_chan_config = {
.sibling_chan = NULL,
.direction = GDMA_CHANNEL_DIRECTION_RX,
.flags = {
.reserve_sibling = 0
}
};
gdma_new_channel(&dma_camrx_chan_config, &dma_camrx_chan);
gdma_connect(dma_camrx_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_CAM, 0));
gdma_strategy_config_t strategy_config = {
.owner_check = false,
.auto_update_desc = false
};
gdma_apply_strategy(dma_camrx_chan, &strategy_config);
// Enable DMA transfer callback
gdma_rx_event_callbacks_t rx_cbs = {
.on_recv_eof = dma_callback
};
gdma_register_rx_event_callbacks(dma_camrx_chan, &rx_cbs, NULL);
// Here OV5640 camera configuration code using I2C
//////////////////////
// Camera interface is ok checked with a logic analyzer (xclk, pclk, vsync and href)
delay(50);
gdma_reset(dma_camrx_chan); // Reset DMA to known state
LCD_CAM.cam_ctrl.cam_update = 1; // Update registers
LCD_CAM.cam_ctrl1.cam_afifo_reset = 1;
gdma_start(dma_camrx_chan, (intptr_t)&desc); // Start DMA
LCD_CAM.cam_ctrl1.cam_start = 1; // Trigger CAM DMA transfer
}
void loop() {
delay(10);
}
`
Beta Was this translation helpful? Give feedback.
All reactions
-
The camera driver is public and open source, I suggest you look there. It is not a basic task to get it going and here is not the place to discuss such topics really. What is the reason not to use the already developed driver?
Beta Was this translation helpful? Give feedback.
All reactions
-
Hello, I have reviewed the CameraWebServer.ino file and I think it does not support my requirements.
My goal is to stream the video from the camera by sending UDP Multicast datagrams with the minimum delay.
I managed to do this years ago in an ESP32 using the I2S peripheral and DMA , based on esp32-camera.
Now I want to achieve the same in an ESP32-S3 using the new LCD_CAM peripheral and GDMA, for which
I am basing myself on https://blog.adafruit.com/2022/06/21/esp32uesday-more-s3-lcd-peripheral-hacking-with-code/
Regards.
Beta Was this translation helpful? Give feedback.
All reactions
-
how you transfer is outside of the question. The driver provides you with a good way to grab a frame as soon as it's ready. What you do wit it from then on it does not matter. Your answers is outside of the camera driver and I strongly suggest that you use it.
Beta Was this translation helpful? Give feedback.
All reactions
-
ok, I will use the camera driver, thanks.
Beta Was this translation helpful? Give feedback.