Skip to content

Commit b7d65d9

Browse files
committed
feat(lcd_cam): add lc_dma_int value atomic protect for lcd and cam
1 parent 8008347 commit b7d65d9

File tree

6 files changed

+38
-6
lines changed

6 files changed

+38
-6
lines changed

components/esp_lcd/i80/esp_lcd_panel_io_i80.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,9 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc
199199
(uint32_t)lcd_ll_get_interrupt_status_reg(bus->hal.dev),
200200
LCD_LL_EVENT_TRANS_DONE, i80_lcd_default_isr_handler, bus, &bus->intr);
201201
ESP_GOTO_ON_ERROR(ret, err, TAG, "install interrupt failed");
202-
lcd_ll_enable_interrupt(bus->hal.dev, LCD_LL_EVENT_TRANS_DONE, false); // disable all interrupts
202+
PERIPH_RCC_ATOMIC() {
203+
lcd_ll_enable_interrupt(bus->hal.dev, LCD_LL_EVENT_TRANS_DONE, false); // disable all interrupts
204+
}
203205
lcd_ll_clear_interrupt_status(bus->hal.dev, UINT32_MAX); // clear pending interrupt
204206
// install DMA service
205207
bus->max_transfer_bytes = bus_config->max_transfer_bytes;
@@ -215,8 +217,10 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc
215217
lcd_ll_set_swizzle_mode(bus->hal.dev, LCD_LL_SWIZZLE_AB2BA);
216218
// number of data cycles is controlled by DMA buffer size
217219
lcd_ll_enable_output_always_on(bus->hal.dev, true);
218-
// enable trans done interrupt
219-
lcd_ll_enable_interrupt(bus->hal.dev, LCD_LL_EVENT_TRANS_DONE, true);
220+
PERIPH_RCC_ATOMIC() {
221+
// enable trans done interrupt
222+
lcd_ll_enable_interrupt(bus->hal.dev, LCD_LL_EVENT_TRANS_DONE, true);
223+
}
220224
// trigger a quick "trans done" event, and wait for the interrupt line goes active
221225
// this could ensure we go into ISR handler next time we call `esp_intr_enable`
222226
lcd_periph_trigger_quick_trans_done_event(bus);

components/esp_lcd/rgb/esp_lcd_panel_rgb.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,9 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf
336336
(uint32_t)lcd_ll_get_interrupt_status_reg(rgb_panel->hal.dev),
337337
LCD_LL_EVENT_VSYNC_END, rgb_lcd_default_isr_handler, rgb_panel, &rgb_panel->intr);
338338
ESP_GOTO_ON_ERROR(ret, err, TAG, "install interrupt failed");
339-
lcd_ll_enable_interrupt(rgb_panel->hal.dev, LCD_LL_EVENT_VSYNC_END, false); // disable all interrupts
339+
PERIPH_RCC_ATOMIC() {
340+
lcd_ll_enable_interrupt(rgb_panel->hal.dev, LCD_LL_EVENT_VSYNC_END, false); // disable all interrupts
341+
}
340342
lcd_ll_clear_interrupt_status(rgb_panel->hal.dev, UINT32_MAX); // clear pending interrupt
341343

342344
// install DMA service
@@ -573,8 +575,10 @@ static esp_err_t rgb_panel_init(esp_lcd_panel_t *panel)
573575
// in stream mode, after finish one frame, the LCD controller will ask for data automatically from the DMA
574576
// DMA should prepare the next frame data within porch region
575577
lcd_ll_enable_auto_next_frame(rgb_panel->hal.dev, rgb_panel->flags.stream_mode);
576-
// trigger interrupt on the end of frame
577-
lcd_ll_enable_interrupt(rgb_panel->hal.dev, LCD_LL_EVENT_VSYNC_END, true);
578+
PERIPH_RCC_ATOMIC() {
579+
// trigger interrupt on the end of frame
580+
lcd_ll_enable_interrupt(rgb_panel->hal.dev, LCD_LL_EVENT_VSYNC_END, true);
581+
}
578582
// enable intr
579583
esp_intr_enable(rgb_panel->intr);
580584
// start transmission

components/hal/esp32p4/include/hal/cam_ll.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,12 @@ static inline void cam_ll_enable_interrupt(lcd_cam_dev_t *dev, uint32_t mask, bo
611611
dev->lc_dma_int_ena.val &= ~(mask & 0x0c);
612612
}
613613
}
614+
/// use a macro to wrap the function, force the caller to use it in a critical section
615+
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
616+
#define cam_ll_enable_interrupt(...) do { \
617+
(void)__DECLARE_RCC_ATOMIC_ENV; \
618+
cam_ll_enable_interrupt(__VA_ARGS__); \
619+
} while(0)
614620

615621
/**
616622
* @brief Get interrupt status value

components/hal/esp32p4/include/hal/lcd_ll.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,12 @@ static inline void lcd_ll_enable_interrupt(lcd_cam_dev_t *dev, uint32_t mask, bo
749749
dev->lc_dma_int_ena.val &= ~(mask & 0x03);
750750
}
751751
}
752+
/// use a macro to wrap the function, force the caller to use it in a critical section
753+
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
754+
#define lcd_ll_enable_interrupt(...) do { \
755+
(void)__DECLARE_RCC_ATOMIC_ENV; \
756+
lcd_ll_enable_interrupt(__VA_ARGS__); \
757+
} while(0)
752758

753759
/**
754760
* @brief Get interrupt status value

components/hal/esp32s3/include/hal/cam_ll.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,12 @@ static inline void cam_ll_enable_interrupt(lcd_cam_dev_t *dev, uint32_t mask, bo
574574
dev->lc_dma_int_ena.val &= ~(mask & 0x0c);
575575
}
576576
}
577+
/// use a macro to wrap the function, force the caller to use it in a critical section
578+
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
579+
#define cam_ll_enable_interrupt(...) do { \
580+
(void)__DECLARE_RCC_ATOMIC_ENV; \
581+
cam_ll_enable_interrupt(__VA_ARGS__); \
582+
} while(0)
577583

578584
/**
579585
* @brief Get interrupt status value

components/hal/esp32s3/include/hal/lcd_ll.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,12 @@ static inline void lcd_ll_enable_interrupt(lcd_cam_dev_t *dev, uint32_t mask, bo
723723
dev->lc_dma_int_ena.val &= ~(mask & 0x03);
724724
}
725725
}
726+
/// use a macro to wrap the function, force the caller to use it in a critical section
727+
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
728+
#define lcd_ll_enable_interrupt(...) do { \
729+
(void)__DECLARE_RCC_ATOMIC_ENV; \
730+
lcd_ll_enable_interrupt(__VA_ARGS__); \
731+
} while(0)
726732

727733
/**
728734
* @brief Get interrupt status value

0 commit comments

Comments
 (0)