Skip to content

Commit e69c4af

Browse files
committed
Merge branch 'feature/add_riscv_software_swap_byte' into 'master'
feat(esp_video): Add RISC-V software swap byte function for DVP video device Closes AEG-2815 See merge request espressif/esp-video-components!333
2 parents 5abb193 + a4b5d4d commit e69c4af

File tree

11 files changed

+338
-6
lines changed

11 files changed

+338
-6
lines changed

esp_cam_sensor/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
- Added option to return byte swap flags for GC0308
6+
37
## 1.4.0
48

59
- Update driver dependency, not rely on old `driver` component anymore

esp_cam_sensor/sensors/gc0308/gc0308.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,20 @@ static esp_err_t gc0308_query_para_desc(esp_cam_sensor_device_t *dev, esp_cam_se
274274

275275
static esp_err_t gc0308_get_para_value(esp_cam_sensor_device_t *dev, uint32_t id, void *arg, size_t size)
276276
{
277-
return ESP_ERR_NOT_SUPPORTED;
277+
esp_err_t ret = ESP_OK;
278+
279+
switch (id) {
280+
#if CONFIG_CAMERA_SENSOR_SWAP_PIXEL_BYTE_ORDER
281+
case ESP_CAM_SENSOR_DATA_SEQ:
282+
*(uint32_t *)arg = ESP_CAM_SENSOR_DATA_SEQ_BYTE_SWAPPED;
283+
break;
284+
#endif
285+
default:
286+
ret = ESP_ERR_NOT_SUPPORTED;
287+
break;
288+
}
289+
290+
return ret;
278291
}
279292

280293
static esp_err_t gc0308_set_para_value(esp_cam_sensor_device_t *dev, uint32_t id, const void *arg, size_t size)

esp_video/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## Unreleased
22

3+
- Add RISC-V software swap byte function for DVP video device
34
- Add the customized video class to call esp_cam_sensor ioctl commands directly
45
- Add the second SPI video device
56
- Improve AEC controller time precision

esp_video/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ if(CONFIG_IDF_TARGET_ESP32P4)
1919

2020
if(CONFIG_ESP_VIDEO_ENABLE_SWAP_BYTE)
2121
list(APPEND srcs "src/data_reprocessing/esp32p4/esp_video_swap_byte.c")
22+
list(APPEND srcs "src/data_reprocessing/esp32p4/esp_video_swap_byte.S")
2223
endif()
2324
endif()
2425

esp_video/private_include/esp_video_swap_byte.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
#include "sdkconfig.h"
1010
#include "esp_err.h"
1111
#include "esp_cam_sensor.h"
12+
#if CONFIG_ESP_VIDEO_ENABLE_SWAP_BYTE_BITSCRAMBLER
1213
#include "driver/bitscrambler.h"
14+
#endif
1315

1416
#ifdef __cplusplus
1517
extern "C" {
@@ -19,7 +21,11 @@ extern "C" {
1921
* @brief Video swap byte object
2022
*/
2123
typedef struct esp_video_swap_byte {
24+
#if CONFIG_ESP_VIDEO_ENABLE_SWAP_BYTE_BITSCRAMBLER
2225
bitscrambler_handle_t bs; /*!< Bitscrambler handle */
26+
#else
27+
void *priv; /*!< Swap short byte data */
28+
#endif
2329
} esp_video_swap_byte_t;
2430

2531
/**
@@ -49,6 +55,23 @@ esp_err_t esp_video_swap_byte_start(esp_video_swap_byte_t *swap_byte);
4955
*/
5056
void esp_video_swap_byte_free(esp_video_swap_byte_t *swap_byte);
5157

58+
/**
59+
* @brief Process video swap byte
60+
*
61+
* @param swap_byte Video swap byte object pointer
62+
* @param src Source buffer pointer
63+
* @param src_size Source buffer size
64+
* @param dst Destination buffer pointer
65+
* @param dst_size Destination buffer size
66+
* @param ret_size Result data size buffer
67+
*
68+
* @return
69+
* - ESP_OK on success
70+
* - Others if failed
71+
*/
72+
esp_err_t esp_video_swap_byte_process(esp_video_swap_byte_t *swap_byte, void *src, size_t src_size,
73+
void *dst, size_t dst_size, size_t *ret_size);
74+
5275
#ifdef __cplusplus
5376
}
5477
#endif

esp_video/src/data_reprocessing/Kconfig.data_reprocessing

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,10 @@ menuconfig ESP_VIDEO_ENABLE_SWAP_SHORT
222222

223223
endif # ESP_VIDEO_ENABLE_SWAP_SHORT
224224

225-
config ESP_VIDEO_ENABLE_SWAP_BYTE
225+
menuconfig ESP_VIDEO_ENABLE_SWAP_BYTE
226226
bool "Enable 8-bit data swapping"
227227
default y
228228
select ESP_VIDEO_ENABLE_DATA_PREPROCESSING
229-
select ESP_VIDEO_ENABLE_BITSCRAMBLER
230229
depends on SOC_BITSCRAMBLER_SUPPORTED && ESP_VIDEO_ENABLE_DVP_VIDEO_DEVICE
231230
help
232231
Enable swapping of 8-bit (byte) data for DVP video streams.
@@ -245,4 +244,54 @@ config ESP_VIDEO_ENABLE_SWAP_BYTE
245244

246245
Required for proper color reproduction with many DVP camera modules.
247246
Uses hardware bitscrambler for efficient processing without CPU overhead.
247+
248+
if ESP_VIDEO_ENABLE_SWAP_BYTE
249+
choice ESP_VIDEO_ENABLE_SWAP_BYTE_IMPL
250+
prompt "8-bit swap implementation method"
251+
default ESP_VIDEO_ENABLE_SWAP_BYTE_RISCV
252+
help
253+
Select the implementation method for 8-bit data swapping.
254+
255+
Performance comparison (typical):
256+
- RISC-V Assembly: Fast, uses CPU cores
257+
- Hardware Bitscrambler: Fastest, offloads CPU but uses peripheral
258+
259+
Choose based on your performance requirements and available peripherals.
260+
261+
config ESP_VIDEO_ENABLE_SWAP_BYTE_RISCV
262+
bool "RISC-V assembly instructions"
263+
help
264+
Use optimized RISC-V assembly instructions for data swapping.
265+
266+
Benefits:
267+
- Fast execution speed
268+
- Low latency processing
269+
- No peripheral dependencies
270+
271+
Trade-offs:
272+
- Uses CPU cycles
273+
- May affect other real-time tasks
274+
275+
Best for: High-performance applications where speed is critical.
276+
277+
config ESP_VIDEO_ENABLE_SWAP_BYTE_BITSCRAMBLER
278+
bool "Hardware bitscrambler - Experimental"
279+
select ESP_VIDEO_ENABLE_BITSCRAMBLER
280+
depends on SOC_BITSCRAMBLER_SUPPORTED
281+
help
282+
Use dedicated hardware bitscrambler peripheral for data swapping.
283+
284+
Benefits:
285+
- Offloads CPU processing
286+
- Allows CPU to handle other tasks
287+
- No impact on real-time performance
288+
289+
Trade-offs:
290+
- Faster than CPU-based methods without latency
291+
- Requires available peripheral
292+
- Experimental feature
293+
294+
Best for: Applications where CPU resources are constrained.
295+
endchoice # ESP_VIDEO_ENABLE_SWAP_BYTE_IMPL
296+
endif #ESP_VIDEO_ENABLE_SWAP_BYTE
248297
endmenu
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: ESPRESSIF MIT
5+
*/
6+
7+
/**
8+
* @brief Swap byte data based on RISC-V instruction
9+
*
10+
* @param a0 Source buffer pointer
11+
* @param a1 Destination buffer pointer
12+
* @param a2 Buffer size
13+
*
14+
* @Note void esp_video_swap_byte_riscv(void *src, void *dst, size_t size);
15+
*/
16+
.text
17+
.section .text.esp_video_swap_byte_riscv, "ax"
18+
.global esp_video_swap_byte_riscv
19+
.type esp_video_swap_byte_riscv,@function
20+
.align 4
21+
esp_video_swap_byte_riscv:
22+
addi sp, sp, -32
23+
sw s0, 0(sp)
24+
sw s1, 4(sp)
25+
sw s2, 8(sp)
26+
sw s3, 12(sp)
27+
sw s4, 16(sp)
28+
sw s5, 20(sp)
29+
30+
add a2, a0, a2
31+
li s4, 0xff00ff00
32+
li s5, 0x00ff00ff
33+
34+
esp_video_swap_byte_riscv_loop:
35+
lw a3, 0(a0)
36+
lw a4, 4(a0)
37+
lw a5, 8(a0)
38+
lw a6, 12(a0)
39+
lw a7, 16(a0)
40+
lw s0, 20(a0)
41+
lw s1, 24(a0)
42+
lw s2, 28(a0)
43+
44+
srli s3, a3, 8
45+
and s3, s3, s5
46+
slli a3, a3, 8
47+
and a3, a3, s4
48+
or a3, a3, s3
49+
sw a3, 0(a1)
50+
51+
srli s3, a4, 8
52+
and s3, s3, s5
53+
slli a4, a4, 8
54+
and a4, a4, s4
55+
or a4, a4, s3
56+
sw a4, 4(a1)
57+
58+
srli s3, a5, 8
59+
and s3, s3, s5
60+
slli a5, a5, 8
61+
and a5, a5, s4
62+
or a5, a5, s3
63+
sw a5, 8(a1)
64+
65+
srli s3, a6, 8
66+
and s3, s3, s5
67+
slli a6, a6, 8
68+
and a6, a6, s4
69+
or a6, a6, s3
70+
sw a6, 12(a1)
71+
72+
srli s3, a7, 8
73+
and s3, s3, s5
74+
slli a7, a7, 8
75+
and a7, a7, s4
76+
or a7, a7, s3
77+
sw a7, 16(a1)
78+
79+
srli s3, s0, 8
80+
and s3, s3, s5
81+
slli s0, s0, 8
82+
and s0, s0, s4
83+
or s0, s0, s3
84+
sw s0, 20(a1)
85+
86+
srli s3, s1, 8
87+
and s3, s3, s5
88+
slli s1, s1, 8
89+
and s1, s1, s4
90+
or s1, s1, s3
91+
sw s1, 24(a1)
92+
93+
srli s3, s2, 8
94+
and s3, s3, s5
95+
slli s2, s2, 8
96+
and s2, s2, s4
97+
or s2, s2, s3
98+
sw s2, 28(a1)
99+
100+
addi a0, a0, 32
101+
addi a1, a1, 32
102+
bltu a0, a2, esp_video_swap_byte_riscv_loop
103+
104+
lw s0, 0(sp)
105+
lw s1, 4(sp)
106+
lw s2, 8(sp)
107+
lw s3, 12(sp)
108+
lw s4, 16(sp)
109+
lw s5, 20(sp)
110+
addi sp, sp, 32
111+
112+
ret

esp_video/src/data_reprocessing/esp32p4/esp_video_swap_byte.c

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313

1414
static const char *TAG = "swap_byte";
1515

16+
#if CONFIG_ESP_VIDEO_ENABLE_SWAP_BYTE_BITSCRAMBLER
1617
BITSCRAMBLER_PROGRAM(esp_video_swap_byte, "esp_video_swap_byte");
18+
#elif CONFIG_ESP_VIDEO_ENABLE_SWAP_BYTE_RISCV
19+
extern void esp_video_swap_byte_riscv(void *src, void *dst, uint32_t size);
20+
#endif
1721

1822
/**
1923
* @brief Create video swap byte
@@ -22,14 +26,17 @@ BITSCRAMBLER_PROGRAM(esp_video_swap_byte, "esp_video_swap_byte");
2226
*/
2327
esp_video_swap_byte_t *esp_video_swap_byte_create(void)
2428
{
25-
esp_err_t ret;
2629
esp_video_swap_byte_t *swap_byte;
2730

2831
swap_byte = heap_caps_calloc(1, sizeof(esp_video_swap_byte_t), MALLOC_CAP_8BIT | MALLOC_CAP_8BIT);
2932
if (!swap_byte) {
33+
ESP_LOGE(TAG, "Failed to allocate memory for swap byte");
3034
return NULL;
3135
}
3236

37+
#if CONFIG_ESP_VIDEO_ENABLE_SWAP_BYTE_BITSCRAMBLER
38+
esp_err_t ret;
39+
3340
bitscrambler_config_t bs_config = {
3441
.dir = BITSCRAMBLER_DIR_RX,
3542
.attach_to = SOC_BITSCRAMBLER_ATTACH_LCD_CAM,
@@ -52,6 +59,9 @@ esp_video_swap_byte_t *esp_video_swap_byte_create(void)
5259
exit_0:
5360
heap_caps_free(swap_byte);
5461
return NULL;
62+
#else
63+
return swap_byte;
64+
#endif
5565
}
5666

5767
/**
@@ -65,6 +75,7 @@ esp_video_swap_byte_t *esp_video_swap_byte_create(void)
6575
*/
6676
esp_err_t IRAM_ATTR esp_video_swap_byte_start(esp_video_swap_byte_t *swap_byte)
6777
{
78+
#if CONFIG_ESP_VIDEO_ENABLE_SWAP_BYTE_BITSCRAMBLER
6879
esp_err_t ret;
6980

7081
if ((ret = bitscrambler_reset(swap_byte->bs)) != ESP_OK) {
@@ -78,6 +89,9 @@ esp_err_t IRAM_ATTR esp_video_swap_byte_start(esp_video_swap_byte_t *swap_byte)
7889
}
7990

8091
return ESP_OK;
92+
#else
93+
return ESP_OK;
94+
#endif
8195
}
8296

8397
/**
@@ -89,8 +103,35 @@ esp_err_t IRAM_ATTR esp_video_swap_byte_start(esp_video_swap_byte_t *swap_byte)
89103
*/
90104
void esp_video_swap_byte_free(esp_video_swap_byte_t *swap_byte)
91105
{
106+
#if CONFIG_ESP_VIDEO_ENABLE_SWAP_BYTE_BITSCRAMBLER
92107
bitscrambler_reset(swap_byte->bs);
93108
bitscrambler_disable(swap_byte->bs);
94109
bitscrambler_free(swap_byte->bs);
95-
swap_byte->bs = NULL;
110+
#endif
111+
112+
heap_caps_free(swap_byte);
113+
}
114+
115+
/**
116+
* @brief Process video swap byte
117+
*
118+
* @param swap_byte Video swap byte object pointer
119+
* @param src Source buffer pointer
120+
* @param src_size Source buffer size
121+
* @param dst Destination buffer pointer
122+
* @param dst_size Destination buffer size
123+
* @param ret_size Result data size buffer
124+
*
125+
* @return
126+
* - ESP_OK on success
127+
* - Others if failed
128+
*/
129+
esp_err_t esp_video_swap_byte_process(esp_video_swap_byte_t *swap_byte, void *src, size_t src_size,
130+
void *dst, size_t dst_size, size_t *ret_size)
131+
{
132+
#if CONFIG_ESP_VIDEO_ENABLE_SWAP_BYTE_RISCV
133+
esp_video_swap_byte_riscv(src, dst, src_size);
134+
#endif
135+
*ret_size = src_size;
136+
return ESP_OK;
96137
}

esp_video/src/data_reprocessing/esp32p4/esp_video_swap_short.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,4 +178,6 @@ void esp_video_swap_short_free(esp_video_swap_short_t *swap_short)
178178
#if CONFIG_ESP_VIDEO_ENABLE_SWAP_SHORT_BITSCRAMBLER
179179
bitscrambler_free((bitscrambler_handle_t)swap_short->priv);
180180
#endif
181+
182+
heap_caps_free(swap_short);
181183
}

0 commit comments

Comments
 (0)