Skip to content

Commit f0bb429

Browse files
authored
Implement proper GDMA allocator and ISR from IRAM option (#629)
* Implement proper GDMA allocator * Add Kconfig option to execute ISR from IRAM on S2 and S3 Up until now, default was to execute from IRAM. This changes that for S2 and S3. ESP32 is left unchanged, because of the work that is required on it.
1 parent 984999f commit f0bb429

File tree

4 files changed

+102
-49
lines changed

4 files changed

+102
-49
lines changed

Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,11 @@ menu "Camera configuration"
210210
Full color range mode has a wider color range, so details in the image show more clearly.
211211
Please confirm the color range mode of the current camera sensor, incorrect color range mode may cause color difference in the final converted image.
212212
Full range mode is used by default. If this option is not selected, the format conversion function will be done using the limited range mode.
213+
214+
config LCD_CAM_ISR_IRAM_SAFE
215+
bool "Execute camera ISR from IRAM"
216+
depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
217+
default n
218+
help
219+
If this option is enabled, camera ISR will execute from IRAM.
213220
endmenu

target/esp32s2/ll_cam.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static const char *TAG = "s2 ll_cam";
3737
#define I2S_ISR_ENABLE(i) {I2S0.int_clr.i = 1;I2S0.int_ena.i = 1;}
3838
#define I2S_ISR_DISABLE(i) {I2S0.int_ena.i = 0;I2S0.int_clr.i = 1;}
3939

40-
static void IRAM_ATTR ll_cam_vsync_isr(void *arg)
40+
static void CAMERA_ISR_IRAM_ATTR ll_cam_vsync_isr(void *arg)
4141
{
4242
//DBG_PIN_SET(1);
4343
cam_obj_t *cam = (cam_obj_t *)arg;
@@ -54,7 +54,7 @@ static void IRAM_ATTR ll_cam_vsync_isr(void *arg)
5454
//DBG_PIN_SET(0);
5555
}
5656

57-
static void IRAM_ATTR ll_cam_dma_isr(void *arg)
57+
static void CAMERA_ISR_IRAM_ATTR ll_cam_dma_isr(void *arg)
5858
{
5959
cam_obj_t *cam = (cam_obj_t *)arg;
6060
BaseType_t HPTaskAwoken = pdFALSE;
@@ -217,7 +217,7 @@ esp_err_t ll_cam_set_pin(cam_obj_t *cam, const camera_config_t *config)
217217
io_conf.pull_up_en = 1;
218218
io_conf.pull_down_en = 0;
219219
gpio_config(&io_conf);
220-
gpio_install_isr_service(ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM);
220+
gpio_install_isr_service(ESP_INTR_FLAG_LOWMED | CAMERA_ISR_IRAM_FLAG);
221221
gpio_isr_handler_add(config->pin_vsync, ll_cam_vsync_isr, cam);
222222
gpio_intr_disable(config->pin_vsync);
223223

@@ -255,7 +255,7 @@ esp_err_t ll_cam_set_pin(cam_obj_t *cam, const camera_config_t *config)
255255

256256
esp_err_t ll_cam_init_isr(cam_obj_t *cam)
257257
{
258-
return esp_intr_alloc(ETS_I2S0_INTR_SOURCE, ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM, ll_cam_dma_isr, cam, &cam->cam_intr_handle);
258+
return esp_intr_alloc(ETS_I2S0_INTR_SOURCE, ESP_INTR_FLAG_LOWMED | CAMERA_ISR_IRAM_FLAG, ll_cam_dma_isr, cam, &cam->cam_intr_handle);
259259
}
260260

261261
void ll_cam_do_vsync(cam_obj_t *cam)

target/esp32s3/ll_cam.c

Lines changed: 77 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "soc/gdma_struct.h"
2121
#include "soc/gdma_periph.h"
2222
#include "soc/gdma_reg.h"
23+
#include "hal/clk_gate_ll.h"
24+
#include "esp_private/gdma.h"
2325
#include "ll_cam.h"
2426
#include "cam_hal.h"
2527
#include "esp_rom_gpio.h"
@@ -87,7 +89,7 @@ void ll_cam_dma_reset(cam_obj_t *cam)
8789
//GDMA.channel[cam->dma_num].in.wight.rx_weight = 7;//The weight of Rx channel 0-15
8890
}
8991

90-
static void IRAM_ATTR ll_cam_vsync_isr(void *arg)
92+
static void CAMERA_ISR_IRAM_ATTR ll_cam_vsync_isr(void *arg)
9193
{
9294
//DBG_PIN_SET(1);
9395
cam_obj_t *cam = (cam_obj_t *)arg;
@@ -110,7 +112,7 @@ static void IRAM_ATTR ll_cam_vsync_isr(void *arg)
110112
//DBG_PIN_SET(0);
111113
}
112114

113-
static void IRAM_ATTR ll_cam_dma_isr(void *arg)
115+
static void CAMERA_ISR_IRAM_ATTR ll_cam_dma_isr(void *arg)
114116
{
115117
cam_obj_t *cam = (cam_obj_t *)arg;
116118
BaseType_t HPTaskAwoken = pdFALSE;
@@ -141,25 +143,6 @@ bool IRAM_ATTR ll_cam_stop(cam_obj_t *cam)
141143
return true;
142144
}
143145

144-
esp_err_t ll_cam_deinit(cam_obj_t *cam)
145-
{
146-
if (cam->cam_intr_handle) {
147-
esp_intr_free(cam->cam_intr_handle);
148-
cam->cam_intr_handle = NULL;
149-
}
150-
151-
if (cam->dma_intr_handle) {
152-
esp_intr_free(cam->dma_intr_handle);
153-
cam->dma_intr_handle = NULL;
154-
}
155-
GDMA.channel[cam->dma_num].in.link.addr = 0x0;
156-
157-
LCD_CAM.cam_ctrl1.cam_start = 0;
158-
LCD_CAM.cam_ctrl1.cam_reset = 1;
159-
LCD_CAM.cam_ctrl1.cam_reset = 0;
160-
return ESP_OK;
161-
}
162-
163146
bool ll_cam_start(cam_obj_t *cam, int frame_pos)
164147
{
165148
LCD_CAM.cam_ctrl1.cam_start = 0;
@@ -191,27 +174,72 @@ bool ll_cam_start(cam_obj_t *cam, int frame_pos)
191174
return true;
192175
}
193176

194-
static esp_err_t ll_cam_dma_init(cam_obj_t *cam)
177+
esp_err_t ll_cam_deinit(cam_obj_t *cam)
195178
{
196-
for (int x = (SOC_GDMA_PAIRS_PER_GROUP - 1); x >= 0; x--) {
197-
if (GDMA.channel[x].in.link.addr == 0x0) {
198-
cam->dma_num = x;
199-
ESP_LOGI(TAG, "DMA Channel=%d", cam->dma_num);
200-
break;
201-
}
202-
if (x == 0) {
203-
cam_deinit();
204-
ESP_LOGE(TAG, "Can't found available GDMA channel");
205-
return ESP_FAIL;
206-
}
179+
if (cam->cam_intr_handle) {
180+
esp_intr_free(cam->cam_intr_handle);
181+
cam->cam_intr_handle = NULL;
207182
}
208183

209-
if (REG_GET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN) == 0) {
210-
REG_CLR_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN);
211-
REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN);
212-
REG_SET_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
213-
REG_CLR_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
184+
if (cam->dma_intr_handle) {
185+
esp_intr_free(cam->dma_intr_handle);
186+
cam->dma_intr_handle = NULL;
187+
}
188+
gdma_disconnect(cam->dma_channel_handle);
189+
gdma_del_channel(cam->dma_channel_handle);
190+
cam->dma_channel_handle = NULL;
191+
// GDMA.channel[cam->dma_num].in.link.addr = 0x0;
192+
193+
LCD_CAM.cam_ctrl1.cam_start = 0;
194+
LCD_CAM.cam_ctrl1.cam_reset = 1;
195+
LCD_CAM.cam_ctrl1.cam_reset = 0;
196+
return ESP_OK;
197+
}
198+
199+
static esp_err_t ll_cam_dma_init(cam_obj_t *cam)
200+
{
201+
//alloc rx gdma channel
202+
gdma_channel_alloc_config_t rx_alloc_config = {
203+
.direction = GDMA_CHANNEL_DIRECTION_RX,
204+
};
205+
esp_err_t ret = gdma_new_channel(&rx_alloc_config, &cam->dma_channel_handle);
206+
if (ret != ESP_OK) {
207+
cam_deinit();
208+
ESP_LOGE(TAG, "Can't find available GDMA channel");
209+
return ESP_FAIL;
210+
}
211+
int chan_id = -1;
212+
ret = gdma_get_channel_id(cam->dma_channel_handle, &chan_id);
213+
if (ret != ESP_OK) {
214+
cam_deinit();
215+
ESP_LOGE(TAG, "Can't get GDMA channel number");
216+
return ESP_FAIL;
217+
}
218+
cam->dma_num = chan_id;
219+
ESP_LOGI(TAG, "DMA Channel=%d", cam->dma_num);
220+
// for (int x = (SOC_GDMA_PAIRS_PER_GROUP - 1); x >= 0; x--) {
221+
// if (GDMA.channel[x].in.link.addr == 0x0) {
222+
// cam->dma_num = x;
223+
// ESP_LOGI(TAG, "DMA Channel=%d", cam->dma_num);
224+
// break;
225+
// }
226+
// if (x == 0) {
227+
// cam_deinit();
228+
// ESP_LOGE(TAG, "Can't found available GDMA channel");
229+
// return ESP_FAIL;
230+
// }
231+
// }
232+
233+
if (!periph_ll_periph_enabled(PERIPH_GDMA_MODULE)) {
234+
periph_ll_disable_clk_set_rst(PERIPH_GDMA_MODULE);
235+
periph_ll_enable_clk_clear_rst(PERIPH_GDMA_MODULE);
214236
}
237+
// if (REG_GET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN) == 0) {
238+
// REG_CLR_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN);
239+
// REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN);
240+
// REG_SET_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
241+
// REG_CLR_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
242+
// }
215243
ll_cam_dma_reset(cam);
216244
return ESP_OK;
217245
}
@@ -267,12 +295,16 @@ static esp_err_t ll_cam_converter_config(cam_obj_t *cam, const camera_config_t *
267295
esp_err_t ll_cam_config(cam_obj_t *cam, const camera_config_t *config)
268296
{
269297
esp_err_t ret = ESP_OK;
270-
if (REG_GET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_LCD_CAM_CLK_EN) == 0) {
271-
REG_CLR_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_LCD_CAM_CLK_EN);
272-
REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_LCD_CAM_CLK_EN);
273-
REG_SET_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_LCD_CAM_RST);
274-
REG_CLR_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_LCD_CAM_RST);
298+
if (!periph_ll_periph_enabled(PERIPH_LCD_CAM_MODULE)) {
299+
periph_ll_disable_clk_set_rst(PERIPH_LCD_CAM_MODULE);
300+
periph_ll_enable_clk_clear_rst(PERIPH_LCD_CAM_MODULE);
275301
}
302+
// if (REG_GET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_LCD_CAM_CLK_EN) == 0) {
303+
// REG_CLR_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_LCD_CAM_CLK_EN);
304+
// REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_LCD_CAM_CLK_EN);
305+
// REG_SET_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_LCD_CAM_RST);
306+
// REG_CLR_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_LCD_CAM_RST);
307+
// }
276308

277309
LCD_CAM.cam_ctrl.val = 0;
278310

@@ -369,7 +401,7 @@ esp_err_t ll_cam_init_isr(cam_obj_t *cam)
369401
{
370402
esp_err_t ret = ESP_OK;
371403
ret = esp_intr_alloc_intrstatus(gdma_periph_signals.groups[0].pairs[cam->dma_num].rx_irq_id,
372-
ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM,
404+
ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED | CAMERA_ISR_IRAM_FLAG,
373405
(uint32_t)&GDMA.channel[cam->dma_num].in.int_st, GDMA_IN_SUC_EOF_CH0_INT_ST_M,
374406
ll_cam_dma_isr, cam, &cam->dma_intr_handle);
375407
if (ret != ESP_OK) {
@@ -378,7 +410,7 @@ esp_err_t ll_cam_init_isr(cam_obj_t *cam)
378410
}
379411

380412
ret = esp_intr_alloc_intrstatus(ETS_LCD_CAM_INTR_SOURCE,
381-
ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM,
413+
ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED | CAMERA_ISR_IRAM_FLAG,
382414
(uint32_t)&LCD_CAM.lc_dma_int_st.val, LCD_CAM_CAM_VSYNC_INT_ST_M,
383415
ll_cam_vsync_isr, cam, &cam->cam_intr_handle);
384416
if (ret != ESP_OK) {

target/private_include/ll_cam.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@
3838
#if __has_include("esp_private/periph_ctrl.h")
3939
# include "esp_private/periph_ctrl.h"
4040
#endif
41+
#if __has_include("esp_private/gdma.h")
42+
# include "esp_private/gdma.h"
43+
#endif
44+
45+
#if CONFIG_LCD_CAM_ISR_IRAM_SAFE
46+
#define CAMERA_ISR_IRAM_FLAG ESP_INTR_FLAG_IRAM
47+
#define CAMERA_ISR_IRAM_ATTR IRAM_ATTR
48+
#else
49+
#define CAMERA_ISR_IRAM_FLAG 0
50+
#define CAMERA_ISR_IRAM_ATTR
51+
#endif
4152

4253
#define CAMERA_DBG_PIN_ENABLE 0
4354
#if CAMERA_DBG_PIN_ENABLE
@@ -104,6 +115,9 @@ typedef struct {
104115

105116
uint8_t dma_num;//ESP32-S3
106117
intr_handle_t dma_intr_handle;//ESP32-S3
118+
#if SOC_GDMA_SUPPORTED
119+
gdma_channel_handle_t dma_channel_handle;//ESP32-S3
120+
#endif
107121

108122
uint8_t jpeg_mode;
109123
uint8_t vsync_pin;

0 commit comments

Comments
 (0)