Skip to content

Commit b4c0530

Browse files
authored
Merge pull request #2435 from hathach/enhance-uvc
Enhance UVC decriptors and example
2 parents bd3c4fb + 5595065 commit b4c0530

File tree

9 files changed

+639
-166
lines changed

9 files changed

+639
-166
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# This file is for ESP-IDF only
2+
idf_component_register(SRCS "main.c" "usb_descriptors.c"
3+
INCLUDE_DIRS "."
4+
REQUIRES boards tinyusb_src)

examples/device/video_capture/src/main.c

Lines changed: 117 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,25 @@ enum {
4848

4949
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
5050

51-
void led_blinking_task(void);
52-
void video_task(void);
51+
void led_blinking_task(void* param);
52+
void usb_device_task(void *param);
53+
void video_task(void* param);
5354

54-
/*------------- MAIN -------------*/
55+
#if CFG_TUSB_OS == OPT_OS_FREERTOS
56+
void freertos_init_task(void);
57+
#endif
58+
59+
60+
//--------------------------------------------------------------------+
61+
// Main
62+
//--------------------------------------------------------------------+
5563
int main(void) {
5664
board_init();
5765

66+
// If using FreeRTOS: create blinky, tinyusb device, video task
67+
#if CFG_TUSB_OS == OPT_OS_FREERTOS
68+
freertos_init_task();
69+
#else
5870
// init device stack on configured roothub port
5971
tud_init(BOARD_TUD_RHPORT);
6072

@@ -64,10 +76,10 @@ int main(void) {
6476

6577
while (1) {
6678
tud_task(); // tinyusb device task
67-
led_blinking_task();
68-
69-
video_task();
79+
led_blinking_task(NULL);
80+
video_task(NULL);
7081
}
82+
#endif
7183
}
7284

7385
//--------------------------------------------------------------------+
@@ -169,7 +181,7 @@ static void fill_color_bar(uint8_t* buffer, unsigned start_position) {
169181

170182
#endif
171183

172-
void video_task(void) {
184+
void video_send_frame(void) {
173185
static unsigned start_ms = 0;
174186
static unsigned already_sent = 0;
175187

@@ -213,6 +225,21 @@ void video_task(void) {
213225
#endif
214226
}
215227

228+
229+
void video_task(void* param) {
230+
(void) param;
231+
232+
while(1) {
233+
video_send_frame();
234+
235+
#if CFG_TUSB_OS == OPT_OS_FREERTOS
236+
vTaskDelay(interval_ms / portTICK_PERIOD_MS);
237+
#else
238+
return;
239+
#endif
240+
}
241+
}
242+
216243
void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) {
217244
(void) ctl_idx;
218245
(void) stm_idx;
@@ -231,16 +258,92 @@ int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx,
231258
}
232259

233260
//--------------------------------------------------------------------+
234-
// BLINKING TASK
261+
// Blinking Task
235262
//--------------------------------------------------------------------+
236-
void led_blinking_task(void) {
263+
void led_blinking_task(void* param) {
264+
(void) param;
237265
static uint32_t start_ms = 0;
238266
static bool led_state = false;
239267

240-
// Blink every interval ms
241-
if (board_millis() - start_ms < blink_interval_ms) return; // not enough time
242-
start_ms += blink_interval_ms;
268+
while (1) {
269+
#if CFG_TUSB_OS == OPT_OS_FREERTOS
270+
vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS);
271+
#else
272+
if (board_millis() - start_ms < blink_interval_ms) return; // not enough time
273+
#endif
274+
275+
start_ms += blink_interval_ms;
276+
board_led_write(led_state);
277+
led_state = 1 - led_state; // toggle
278+
}
279+
}
280+
281+
//--------------------------------------------------------------------+
282+
// FreeRTOS
283+
//--------------------------------------------------------------------+
284+
#if CFG_TUSB_OS == OPT_OS_FREERTOS
285+
286+
#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
287+
#define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4)
288+
289+
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
290+
#define USBD_STACK_SIZE 4096
291+
int main(void);
292+
void app_main(void) {
293+
main();
294+
}
295+
#else
296+
// Increase stack size when debug log is enabled
297+
#define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
298+
#endif
299+
300+
// static task
301+
#if configSUPPORT_STATIC_ALLOCATION
302+
StackType_t blinky_stack[BLINKY_STACK_SIZE];
303+
StaticTask_t blinky_taskdef;
304+
305+
StackType_t usb_device_stack[USBD_STACK_SIZE];
306+
StaticTask_t usb_device_taskdef;
307+
308+
StackType_t video_stack[VIDEO_STACK_SIZE];
309+
StaticTask_t video_taskdef;
310+
#endif
311+
312+
// USB Device Driver task
313+
// This top level thread process all usb events and invoke callbacks
314+
void usb_device_task(void *param) {
315+
(void) param;
316+
317+
// init device stack on configured roothub port
318+
// This should be called after scheduler/kernel is started.
319+
// Otherwise, it could cause kernel issue since USB IRQ handler does use RTOS queue API.
320+
tud_init(BOARD_TUD_RHPORT);
321+
322+
if (board_init_after_tusb) {
323+
board_init_after_tusb();
324+
}
243325

244-
board_led_write(led_state);
245-
led_state = 1 - led_state; // toggle
326+
// RTOS forever loop
327+
while (1) {
328+
// put this thread to waiting state until there is new events
329+
tud_task();
330+
}
246331
}
332+
333+
void freertos_init_task(void) {
334+
#if configSUPPORT_STATIC_ALLOCATION
335+
xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef);
336+
xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef);
337+
xTaskCreateStatic(video_task, "cdc", VIDEO_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, video_stack, &video_taskdef);
338+
#else
339+
xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL);
340+
xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
341+
xTaskCreate(video_task, "video", VIDEO_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL);
342+
#endif
343+
344+
// skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
345+
#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
346+
vTaskStartScheduler();
347+
#endif
348+
}
349+
#endif

examples/device/video_capture/src/tusb_config.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@
5757
#define CFG_TUSB_OS OPT_OS_NONE
5858
#endif
5959

60+
// Espressif IDF requires "freertos/" prefix in include path
61+
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
62+
#define CFG_TUSB_OS_INC_PATH freertos/
63+
#endif
64+
6065
#ifndef CFG_TUSB_DEBUG
6166
#define CFG_TUSB_DEBUG 0
6267
#endif
@@ -103,6 +108,9 @@
103108
// use bulk endpoint for streaming interface
104109
#define CFG_TUD_VIDEO_STREAMING_BULK 1
105110

111+
//#define CFG_EXAMPLE_VIDEO_READONLY
112+
//#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG
113+
106114
#ifdef __cplusplus
107115
}
108116
#endif

0 commit comments

Comments
 (0)