From f212899b54740479eff225d89432d88f0a14f17e Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Mon, 14 Mar 2022 20:40:33 +0100 Subject: Add SOF callback function for feedback value determination in uac - wip! --- src/class/audio/audio_device.c | 83 ++++++++++++++++++++++++++++++++++++++++++ src/class/audio/audio_device.h | 23 +++++++++++- 2 files changed, 105 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 06979b09e..0828f2e6f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -306,6 +306,13 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + uint8_t n_frames; // Number of (micro)frames used to estimate feedback value + uint8_t n_frames_current; // Current (micro)frame number + uint32_t feeback_param_factor; // TODO: Set this value within some new tud_audio_set_feedback_params_fm_fs function as feeback_param_factor = f_s / (f_cpu * n_frames)! +#endif + #endif #endif @@ -421,6 +428,10 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); +#endif + bool tud_audio_n_mounted(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO); @@ -1658,6 +1669,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * { audio->ep_fb = ep_addr; +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + usbd_sof_enable(rhport, true); // Enable SOF interrupt + audio->n_frames_current = 0; +#endif + // Invoke callback after ep_out is set if (audio->ep_out != 0) { @@ -1682,6 +1698,23 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * p_desc = tu_desc_next(p_desc); } + // Disable SOF interrupt if no driver has any enabled feedback EP +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + + bool disable = true; + + for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) + { + if (_audiod_fct[i].ep_fb != 0) + { + disable = false; + } + } + + if (disable) usbd_sof_enable(rhport, false); + +#endif + tud_control_status(rhport, p_request); return true; @@ -1970,6 +2003,52 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 return false; } +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s) +{ + audiod_function_t* audio = &_audiod_fct[func_id]; + uint8_t n_frame = 1; // TODO: finalize that + audio->n_frames = n_frame; + audio->feeback_param_factor = f_s / f_m / n_frame; // TODO: Check the 16.16 precision! + return true; +} +#endif + +void audiod_sof (uint8_t rhport, uint32_t frame_count) +{ + (void) rhport; + (void) frame_count; + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + + // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec + // Boiled down, the feedback value Ff = n_samples / (micro)frame. + // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_cpu) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_cpu is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) + // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_cpu / f_s)), K) + // Ff = n_cycles / n_frames * f_s / f_cpu in 16.16 format, where n_cycles are the number of CPU cycles within n_frames + + // Iterate over audio functions and set feedback value + for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) + { + audiod_function_t* audio = &_audiod_fct[i]; + + if (audio->ep_fb != 0) + { + audio->n_frames_current++; + if (audio->n_frames_current == audio->n_frames) + { + uint32_t n_cylces = tud_audio_n_get_fm_n_cycles_cb(rhport, audio->ep_fb); + uint32_t feedback = n_cylces * audio->feeback_param_factor; + + tud_audio_n_fb_set(i, feedback); + audio->n_frames_current = 0; + } + } + } + +#endif +} + bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_request_t const * p_request, void* data, uint16_t len) { // Handles only sending of data not receiving @@ -2247,7 +2326,11 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) +#else bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) +#endif { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index f406cf281..c9d711a36 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -191,6 +191,11 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 #endif +// Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user +#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 1 // 0 or 1 +#endif + // Audio interrupt control EP size - disabled if 0 #ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN #define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) @@ -468,8 +473,23 @@ TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); // // Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the // driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. + +// Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value. +# if !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); +# else + +// This callback function is called once the feedback value needs to be updated within the SOF ISR in the audio class. To determine the feedback value, some +// parameters need to be given. The user must implement this callback function and provide the current cycle count of the master clock. +// The feedback endpoint number can be used to identify the correct audio function in case multiple audio functions were defined. +TU_ATTR_WEAK uint32_t tud_audio_n_get_fm_n_cycles_cb(uint8_t rhport, uint8_t ep_fb); + +// f_m : Main clock frequency in Hz i.e. master clock to which sample clock is locked +// f_s : Current sample rate in Hz +bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s); +#endif + #endif #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN @@ -611,7 +631,7 @@ static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t l } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR static inline bool tud_audio_fb_set(uint32_t feedback) { return tud_audio_n_fb_set(0, feedback); @@ -626,6 +646,7 @@ void audiod_reset (uint8_t rhport); uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool audiod_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); +void audiod_sof (uint8_t rhport, uint32_t frame_count); #ifdef __cplusplus } -- cgit v1.3.1 From c9b444e771e138ee50ed8cbff67d895722b46008 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Tue, 15 Mar 2022 20:30:31 +0100 Subject: Implement 16.16 fixed point feedback value calculation --- src/class/audio/audio_device.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 0828f2e6f..5ca95658e 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -310,7 +310,8 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR uint8_t n_frames; // Number of (micro)frames used to estimate feedback value uint8_t n_frames_current; // Current (micro)frame number - uint32_t feeback_param_factor; // TODO: Set this value within some new tud_audio_set_feedback_params_fm_fs function as feeback_param_factor = f_s / (f_cpu * n_frames)! + uint32_t feeback_param_factor_N; // Numerator of feedback parameter coefficient + uint32_t feeback_param_factor_D; // Denominator of feedback parameter coefficient #endif #endif @@ -2004,12 +2005,16 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 } #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +// f_s max is 2^19-1 = 524287 Hz +// n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed +// f_m max is 2^29/(1 ms * n_frames) for full speed and 2^29/(125 us * n_frames) for high speed bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s) { audiod_function_t* audio = &_audiod_fct[func_id]; uint8_t n_frame = 1; // TODO: finalize that audio->n_frames = n_frame; - audio->feeback_param_factor = f_s / f_m / n_frame; // TODO: Check the 16.16 precision! + audio->feeback_param_factor_N = f_s << 13; + audio->feeback_param_factor_D = f_m * n_frame; return true; } #endif @@ -2023,7 +2028,7 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec // Boiled down, the feedback value Ff = n_samples / (micro)frame. - // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_cpu) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_cpu is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) + // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_cpu is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_cpu / f_s)), K) // Ff = n_cycles / n_frames * f_s / f_cpu in 16.16 format, where n_cycles are the number of CPU cycles within n_frames @@ -2038,7 +2043,7 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) if (audio->n_frames_current == audio->n_frames) { uint32_t n_cylces = tud_audio_n_get_fm_n_cycles_cb(rhport, audio->ep_fb); - uint32_t feedback = n_cylces * audio->feeback_param_factor; + uint32_t feedback = (n_cylces << 3) * audio->feeback_param_factor_N / audio->feeback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision tud_audio_n_fb_set(i, feedback); audio->n_frames_current = 0; -- cgit v1.3.1 From 90502739c34b8cbcf37229031eb4f575c33311fa Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Tue, 15 Mar 2022 20:45:06 +0100 Subject: Fix cycle count calculation --- src/class/audio/audio_device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 5ca95658e..1dbeb7643 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -310,6 +310,7 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR uint8_t n_frames; // Number of (micro)frames used to estimate feedback value uint8_t n_frames_current; // Current (micro)frame number + uint32_t n_cycles_old; // Old cycle count uint32_t feeback_param_factor_N; // Numerator of feedback parameter coefficient uint32_t feeback_param_factor_D; // Denominator of feedback parameter coefficient #endif @@ -1673,6 +1674,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR usbd_sof_enable(rhport, true); // Enable SOF interrupt audio->n_frames_current = 0; + audio->n_cycles_old = 0; #endif // Invoke callback after ep_out is set @@ -2043,10 +2045,11 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) if (audio->n_frames_current == audio->n_frames) { uint32_t n_cylces = tud_audio_n_get_fm_n_cycles_cb(rhport, audio->ep_fb); - uint32_t feedback = (n_cylces << 3) * audio->feeback_param_factor_N / audio->feeback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision + uint32_t feedback = ((n_cylces - audio->n_cycles_old) << 3) * audio->feeback_param_factor_N / audio->feeback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision tud_audio_n_fb_set(i, feedback); audio->n_frames_current = 0; + audio->n_cycles_old = n_cylces; } } } -- cgit v1.3.1 From 92ac041869b79aba6948e6440bbfc51ba77130ac Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Wed, 16 Mar 2022 07:13:38 +0100 Subject: Add todos and comments --- src/class/audio/audio_device.c | 2 ++ src/device/usbd.c | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 1dbeb7643..37bf76135 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2047,6 +2047,8 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) uint32_t n_cylces = tud_audio_n_get_fm_n_cycles_cb(rhport, audio->ep_fb); uint32_t feedback = ((n_cylces - audio->n_cycles_old) << 3) * audio->feeback_param_factor_N / audio->feeback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision + // TODO: Implement fast computation in case n_frames * f_s / f_m is a power of two + tud_audio_n_fb_set(i, feedback); audio->n_frames_current = 0; audio->n_cycles_old = n_cylces; diff --git a/src/device/usbd.c b/src/device/usbd.c index 6170c2bda..96ac19c8d 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -587,11 +587,12 @@ void tud_task (void) case DCD_EVENT_SOF: TU_LOG2("\r\n"); - for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) - { - usbd_class_driver_t const * driver = get_driver(i); - if ( driver->sof ) driver->sof(event.rhport, event.sof.frame_count); - } + // TODO: Should this really be done here in the queue? How to distinguish the calls here from those SOF events which should be handled directly in the ISR routine? If we do it like this, the SOF routines get called two time right now, once in the ISR context and once again here +// for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) +// { +// usbd_class_driver_t const * driver = get_driver(i); +// if ( driver->sof ) driver->sof(event.rhport, event.sof.frame_count); +// } break; case USBD_EVENT_FUNC_CALL: @@ -1410,6 +1411,7 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) void usbd_sof_enable(uint8_t rhport, bool en) { + // TODO: Check needed if all drivers including the user sof_cb does not need an active SOF ISR any more. Only if all drivers switched off SOF calls the SOF interrupt may be disabled dcd_sof_enable(rhport, en); } -- cgit v1.3.1 From ceac9d64c07b95d2c34263386e212e5480cda97c Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Wed, 16 Mar 2022 08:05:31 +0100 Subject: Disable CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR By default disable CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR such that current examples still work. --- src/class/audio/audio_device.c | 2 +- src/class/audio/audio_device.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 37bf76135..f0cab4d93 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -430,7 +430,7 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); #endif diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index c9d711a36..eba8a6488 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -193,7 +193,7 @@ // Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user #ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 1 // 0 or 1 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 0 // 0 or 1 #endif // Audio interrupt control EP size - disabled if 0 -- cgit v1.3.1 From fdfde8883ff6d929f44706d1fd3ee3cec8702bac Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sat, 19 Mar 2022 13:37:54 +0100 Subject: Implement power of two, shift, and float calculation --- src/class/audio/audio_device.c | 68 +++++++++++++++++++++++++++++++++++------- src/class/audio/audio_device.h | 4 +-- src/common/tusb_common.h | 10 +++++++ 3 files changed, 69 insertions(+), 13 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index f0cab4d93..a815f7557 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -308,11 +308,15 @@ typedef struct uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR - uint8_t n_frames; // Number of (micro)frames used to estimate feedback value - uint8_t n_frames_current; // Current (micro)frame number - uint32_t n_cycles_old; // Old cycle count - uint32_t feeback_param_factor_N; // Numerator of feedback parameter coefficient - uint32_t feeback_param_factor_D; // Denominator of feedback parameter coefficient + uint8_t n_frames; // Number of (micro)frames used to estimate feedback value + uint8_t n_frames_current; // Current (micro)frame number + uint32_t n_cycles_old; // Old cycle count + union { + uint32_t i; + float f; + } feedback_param_factor_N; // Numerator of feedback parameter coefficient + uint32_t feedback_param_factor_D; // Denominator of feedback parameter coefficient + uint32_t * feedback_param_p_cycle_count; // Pointer to cycle counter #endif #endif @@ -2010,14 +2014,39 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 // f_s max is 2^19-1 = 524287 Hz // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed // f_m max is 2^29/(1 ms * n_frames) for full speed and 2^29/(125 us * n_frames) for high speed -bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s) +bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count, bool use_float) { audiod_function_t* audio = &_audiod_fct[func_id]; + audio->feedback_param_p_cycle_count = p_cycle_count; uint8_t n_frame = 1; // TODO: finalize that audio->n_frames = n_frame; - audio->feeback_param_factor_N = f_s << 13; - audio->feeback_param_factor_D = f_m * n_frame; + + + + // Check if parameters reduce to a power of two shift i.e. is n_f * f_m / f_s a power of two? + if ((f_m % f_s) == 0 && tu_is_power_of_two(n_frame * f_m / f_s)) + { + audio->feedback_param_factor_N.i = 0; // zero marks power of two option + audio->feedback_param_factor_D = 16 - tu_log2(n_frame * f_m / f_s); + } + else + { + // Next best option is to use float if a FPU is available - this has to be enabled by the user + if (use_float) + { + audio->feedback_param_factor_N.f = (float)f_s / n_frame / f_m * (1 << 16); + audio->feedback_param_factor_D = 0; // non zero marks float option + } + else + { + // Neither a power of two or floats - use fixed point number + audio->feedback_param_factor_N.i = f_s << 13; + audio->feedback_param_factor_D = f_m * n_frame; + } + } + return true; + } #endif @@ -2044,10 +2073,27 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) audio->n_frames_current++; if (audio->n_frames_current == audio->n_frames) { - uint32_t n_cylces = tud_audio_n_get_fm_n_cycles_cb(rhport, audio->ep_fb); - uint32_t feedback = ((n_cylces - audio->n_cycles_old) << 3) * audio->feeback_param_factor_N / audio->feeback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision + uint32_t n_cylces = *audio->feedback_param_p_cycle_count; + uint32_t feedback; - // TODO: Implement fast computation in case n_frames * f_s / f_m is a power of two + if (audio->feedback_param_factor_N.i == 0) + { + // Power of two shift + feedback = n_cylces << audio->feedback_param_factor_D; + } + else + { + if (audio->feedback_param_factor_D == 0) + { + // Float computation + feedback = (uint32_t)(n_cylces * audio->feedback_param_factor_N.f); + } + else + { + // Fixed point computation + feedback = ((n_cylces - audio->n_cycles_old) << 3) * audio->feedback_param_factor_N.i / audio->feedback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision + } + } tud_audio_n_fb_set(i, feedback); audio->n_frames_current = 0; diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index eba8a6488..3645bda46 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -193,7 +193,7 @@ // Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user #ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 0 // 0 or 1 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 1 // 0 or 1 #endif // Audio interrupt control EP size - disabled if 0 @@ -487,7 +487,7 @@ TU_ATTR_WEAK uint32_t tud_audio_n_get_fm_n_cycles_cb(uint8_t rhport, uint8_t ep_ // f_m : Main clock frequency in Hz i.e. master clock to which sample clock is locked // f_s : Current sample rate in Hz -bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s); +bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count, bool use_float); #endif #endif diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 58591f0be..bcdf8933a 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -149,6 +149,16 @@ static inline uint8_t tu_log2(uint32_t value) return result; } +//static inline uint8_t tu_log2(uint32_t value) +//{ +// return sizeof(uint32_t) * CHAR_BIT - __builtin_clz(x) - 1; +//} + +static inline bool tu_is_power_of_two(uint32_t value) +{ + return (value != 0) && ((value & (value - 1)) == 0); +} + //------------- Unaligned Access -------------// #if TUP_ARCH_STRICT_ALIGN -- cgit v1.3.1 From ff2dc0a5471c3166a1995cc2abb5f42a8a9ab035 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sun, 20 Mar 2022 11:21:33 +0100 Subject: Streamline feedback calc, find fb interval from descriptors, inc. checks --- src/class/audio/audio_device.c | 193 +++++++++++++++++++++++------------------ src/class/audio/audio_device.h | 28 +++++- 2 files changed, 134 insertions(+), 87 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a815f7557..b97155823 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -305,18 +305,29 @@ typedef struct #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). +#if !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). +#endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR - uint8_t n_frames; // Number of (micro)frames used to estimate feedback value - uint8_t n_frames_current; // Current (micro)frame number - uint32_t n_cycles_old; // Old cycle count - union { - uint32_t i; - float f; - } feedback_param_factor_N; // Numerator of feedback parameter coefficient - uint32_t feedback_param_factor_D; // Denominator of feedback parameter coefficient - uint32_t * feedback_param_p_cycle_count; // Pointer to cycle counter + volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value + volatile uint8_t fb_n_frames_current; // Current (micro)frame number + volatile uint32_t fb_n_cycles_old; // Old cycle count + uint32_t * fb_param_p_cycle_count; // Pointer to cycle counter + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT + uint8_t fb_power_of_two_val; +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT + float fb_float_val; +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT + uint64_t fb_param_factor_N; // Numerator of feedback parameter coefficient + uint64_t fb_param_factor_D; // Denominator of feedback parameter coefficient +#endif #endif #endif @@ -1527,7 +1538,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * tu_fifo_clear(&audio->tx_supp_ff[cnt]); } #endif - + // Invoke callback - can be used to stop data sampling if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); @@ -1560,7 +1571,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Close corresponding feedback EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP usbd_edpt_close(rhport, audio->ep_fb); - audio->ep_fb = 0; // Necessary? + audio->ep_fb = 0; #endif } #endif @@ -1677,8 +1688,9 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR usbd_sof_enable(rhport, true); // Enable SOF interrupt - audio->n_frames_current = 0; - audio->n_cycles_old = 0; + audio->fb_n_frames = desc_ep->bInterval; + audio->fb_n_frames_current = 0; + audio->fb_n_cycles_old = 0; #endif // Invoke callback after ep_out is set @@ -1711,12 +1723,12 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * bool disable = true; for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) + { + if (_audiod_fct[i].ep_fb != 0) { - if (_audiod_fct[i].ep_fb != 0) - { - disable = false; - } + disable = false; } + } if (disable) usbd_sof_enable(rhport, false); @@ -2011,40 +2023,56 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 } #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR -// f_s max is 2^19-1 = 524287 Hz -// n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed -// f_m max is 2^29/(1 ms * n_frames) for full speed and 2^29/(125 us * n_frames) for high speed -bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count, bool use_float) + +// This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as +// uint8_t const itf = tu_u16_low(p_request->wIndex); +// uint8_t const alt = tu_u16_low(p_request->wValue); +// such that tud_audio_set_fb_params() gets called with the parameters corresponding to the defined interface and alternate setting +// Also, start the main clock cycle counter (or reset its value) within tud_audio_set_itf_cb() +TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count) { audiod_function_t* audio = &_audiod_fct[func_id]; - audio->feedback_param_p_cycle_count = p_cycle_count; - uint8_t n_frame = 1; // TODO: finalize that - audio->n_frames = n_frame; + audio->fb_param_p_cycle_count = p_cycle_count; + // Check if frame interval is within sane limits + // The interval value audio->fb_n_frames was taken from the descriptors within audiod_set_interface() + // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed - this lower limit ensures the measures feedback value has sufficient precision + if ((TUSB_SPEED_FULL == tud_speed_get() && ((2^10 * f_s / f_m) + 1) > audio->fb_n_frames) || (TUSB_SPEED_HIGH == tud_speed_get() && ((2^13 * f_s / f_m) + 1) > audio->fb_n_frames)) + { + TU_LOG2(" UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false; + } - // Check if parameters reduce to a power of two shift i.e. is n_f * f_m / f_s a power of two? - if ((f_m % f_s) == 0 && tu_is_power_of_two(n_frame * f_m / f_s)) + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT + // Check if parameters really allow for a power of two division + if ((f_m % f_s) != 0 || !tu_is_power_of_two(audio->fb_n_frames * f_m / f_s)) { - audio->feedback_param_factor_N.i = 0; // zero marks power of two option - audio->feedback_param_factor_D = 16 - tu_log2(n_frame * f_m / f_s); + TU_LOG2(" FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT not possible!\r\n"); TU_BREAKPOINT(); return false; } - else + + audio->fb_power_of_two_val = 16 - tu_log2(audio->fb_n_frames * f_m / f_s); +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT + audio->fb_float_val = (float)f_s / audio->fb_n_frames / f_m * (1 << 16); +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT + + // f_s max is 2^19-1 = 524287 Hz + // f_m max is 2^29/(1 ms * n_frames) for full speed and 2^29/(125 us * n_frames) for high speed, this means for f_m fitting in an uint32, n_frames must be < 125 for full speed and < 1000 for high speed (1000 does not fit into uint8 so the maximum possible value cannot even be reached by UAC2 - we don't need to check for it) + + if ((f_s > (2^19)-1) || (TUSB_SPEED_FULL == tud_speed_get() && (audio->fb_n_frames > 125))) { - // Next best option is to use float if a FPU is available - this has to be enabled by the user - if (use_float) - { - audio->feedback_param_factor_N.f = (float)f_s / n_frame / f_m * (1 << 16); - audio->feedback_param_factor_D = 0; // non zero marks float option - } - else - { - // Neither a power of two or floats - use fixed point number - audio->feedback_param_factor_N.i = f_s << 13; - audio->feedback_param_factor_D = f_m * n_frame; - } + // If this check fails, not every thing is lost - you need to re-evaluate the scaling factors of the parameters such that the numbers fit into uint64 again. feedback = n_cycles * S_c / (n_frames * S_n) * f_s * S_s / (f_m * S_m). In the end S_c*S_s / (S_n * S_m) = 2^16 for a 16.16 fixed point precision. If you find something, define your own function of tud_audio_set_feedback_params_fm_fs() and audiod_sof() and use your values + TU_LOG2(" FEEDBACK_DETERMINATION_MODE_FIXED_POINT not possible!\r\n"); TU_BREAKPOINT(); return false; } + audio->fb_param_factor_N = (uint64_t)f_s << 13; + audio->fb_param_factor_D = (uint64_t)f_m * audio->fb_n_frames; +#endif + return true; } @@ -2053,54 +2081,47 @@ bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t void audiod_sof (uint8_t rhport, uint32_t frame_count) { (void) rhport; - (void) frame_count; + (void) frame_count; // frame_count is not used since some devices may not provide the frame count value #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec // Boiled down, the feedback value Ff = n_samples / (micro)frame. - // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_cpu is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) - // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_cpu / f_s)), K) - // Ff = n_cycles / n_frames * f_s / f_cpu in 16.16 format, where n_cycles are the number of CPU cycles within n_frames + // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) + // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_m / f_s)), K) + // feedback = n_cycles / n_frames * f_s / f_m in 16.16 format, where n_cycles are the number of main clock cycles within fb_n_frames // Iterate over audio functions and set feedback value for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) - { - audiod_function_t* audio = &_audiod_fct[i]; + { + audiod_function_t* audio = &_audiod_fct[i]; - if (audio->ep_fb != 0) + if (audio->ep_fb != 0) + { + audio->fb_n_frames_current++; + if (audio->fb_n_frames_current == audio->fb_n_frames) { - audio->n_frames_current++; - if (audio->n_frames_current == audio->n_frames) - { - uint32_t n_cylces = *audio->feedback_param_p_cycle_count; - uint32_t feedback; + uint32_t n_cylces = *audio->fb_param_p_cycle_count; + uint32_t feedback; - if (audio->feedback_param_factor_N.i == 0) - { - // Power of two shift - feedback = n_cylces << audio->feedback_param_factor_D; - } - else - { - if (audio->feedback_param_factor_D == 0) - { - // Float computation - feedback = (uint32_t)(n_cylces * audio->feedback_param_factor_N.f); - } - else - { - // Fixed point computation - feedback = ((n_cylces - audio->n_cycles_old) << 3) * audio->feedback_param_factor_N.i / audio->feedback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision - } - } +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT + feedback = (n_cylces - audio->fb_n_cycles_old) << audio->fb_power_of_two_val; +#endif - tud_audio_n_fb_set(i, feedback); - audio->n_frames_current = 0; - audio->n_cycles_old = n_cylces; - } +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT + feedback = (uint32_t)((float)(n_cylces - audio->fb_n_cycles_old) * audio->fb_float_val); +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT + feedback = ((n_cylces - audio->fb_n_cycles_old) << 3) * audio->fb_param_factor_N / audio->fb_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision +#endif + + tud_audio_n_fb_set(i, feedback); + audio->fb_n_frames_current = 0; + audio->fb_n_cycles_old = n_cylces; } } + } #endif } @@ -2299,6 +2320,16 @@ static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id) // Currently, only AS interfaces with an EP (in or out) are supposed to be parsed for! static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * p_desc, uint8_t const * p_desc_end, uint8_t const as_itf) { +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_in_as_intf_num && as_itf != audio->ep_out_as_intf_num) return; // Abort, this interface has no EP, this driver does not support this currently +#endif +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_in_as_intf_num) return; +#endif +#if !CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_out_as_intf_num) return; +#endif + p_desc = tu_desc_next(p_desc); // Exclude standard AS interface descriptor of current alternate interface descriptor while (p_desc < p_desc_end) @@ -2309,16 +2340,6 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * // Look for a Class-Specific AS Interface Descriptor(4.9.2) to verify format type and format and also to get number of physical channels if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO_CS_AS_INTERFACE_AS_GENERAL) { -#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT - if (as_itf != audio->ep_in_as_intf_num && as_itf != audio->ep_out_as_intf_num) break; // Abort loop, this interface has no EP, this driver does not support this currently -#endif -#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_EP_OUT - if (as_itf != audio->ep_in_as_intf_num) break; -#endif -#if !CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT - if (as_itf != audio->ep_out_as_intf_num) break; -#endif - #if CFG_TUD_AUDIO_ENABLE_EP_IN if (as_itf == audio->ep_in_as_intf_num) { diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 3645bda46..f1bb084d6 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -196,6 +196,25 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 1 // 0 or 1 #endif +// Feeback calculation mode +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT 1 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT 2 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT 3 + +#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE +#error You must tell the driver the feedback determination mode! Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT! +#endif + +#ifdef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT) +#error Unknown CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE. Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT! +#endif +#endif + +#endif + // Audio interrupt control EP size - disabled if 0 #ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN #define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) @@ -487,7 +506,14 @@ TU_ATTR_WEAK uint32_t tud_audio_n_get_fm_n_cycles_cb(uint8_t rhport, uint8_t ep_ // f_m : Main clock frequency in Hz i.e. master clock to which sample clock is locked // f_s : Current sample rate in Hz -bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count, bool use_float); +// p_cycle_count : Pointer to main clock cycle counter register where the current count can be read from (e.g. a timer register) + +// This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as +// uint8_t const itf = tu_u16_low(p_request->wIndex); +// uint8_t const alt = tu_u16_low(p_request->wValue); +// such that tud_audio_set_fb_params() gets called with the parameters corresponding to the defined interface and alternate setting +// Also, start the main clock cycle counter (or reset its value) within tud_audio_set_itf_cb() +TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count); #endif #endif -- cgit v1.3.1 From 5aba4642707e8885b9d10837ac60fb0724d3503f Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sun, 20 Mar 2022 12:04:10 +0100 Subject: Add magic checks --- src/class/audio/audio_device.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index b97155823..386e0ba21 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2116,6 +2116,16 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) feedback = ((n_cylces - audio->fb_n_cycles_old) << 3) * audio->fb_param_factor_N / audio->fb_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision #endif + // Buffer count checks ? + + // Magic checks + if (feedback > 2949166){ // 45.0007 in 16.16 format + feedback = 2949166; + } + if ( feedback < 2883630) { // 44.0007 in 16.16 format + feedback = 2883630; + } + tud_audio_n_fb_set(i, feedback); audio->fb_n_frames_current = 0; audio->fb_n_cycles_old = n_cylces; -- cgit v1.3.1 From 8ffdbfebce56c709b1c2c2396498e9fc32555a77 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sun, 20 Mar 2022 12:08:27 +0100 Subject: Streamline call of tud_audio_set_itf_cb() within audiod_set_interface() --- src/class/audio/audio_device.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 386e0ba21..434bfdcc6 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1631,7 +1631,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif // Invoke callback - can be used to trigger data sampling if not already running - if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); +// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); // Schedule first transmit if alternate interface is not zero i.e. streaming is disabled - in case no sample data is available a ZLP is loaded // It is necessary to trigger this here since the refill is done with an RX FIFO empty interrupt which can only trigger if something was in there @@ -1665,10 +1665,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // In case of asynchronous EP, call Cb after ep_fb is set - if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) ) - { - if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); - } +// if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) ) +// { +// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); +// } #else // Invoke callback if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); @@ -1693,11 +1693,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->fb_n_cycles_old = 0; #endif - // Invoke callback after ep_out is set - if (audio->ep_out != 0) - { - if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); - } +// // Invoke callback after ep_out is set +// if (audio->ep_out != 0) +// { +// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); +// } } #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1709,6 +1709,9 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * TU_VERIFY(foundEPs == nEps); + // Invoke one callback for a final set interface + if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + // We are done - abort loop break; } @@ -2118,7 +2121,7 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) // Buffer count checks ? - // Magic checks + // Magic checks - where are they from? if (feedback > 2949166){ // 45.0007 in 16.16 format feedback = 2949166; } -- cgit v1.3.1 From 5cd67baf15aa24c5f5eae18b9f9615e3af807704 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sun, 20 Mar 2022 12:57:53 +0100 Subject: Disable SOF ISR feedback calcuation by default s.t. examples still work --- src/class/audio/audio_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index f1bb084d6..e5eaed9c7 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -193,7 +193,7 @@ // Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user #ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 1 // 0 or 1 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 0 // 0 or 1 #endif // Feeback calculation mode -- cgit v1.3.1 From e6e3dfedc815007d07ea455df04569604d87a856 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 1 Apr 2022 16:34:36 +0700 Subject: hid example work well --- lib/Pico-PIO-USB | 2 +- src/class/hid/hid_host.c | 2 +- src/host/usbh.c | 2 +- src/portable/raspberrypi/pio/hcd_pio.c | 42 ---------------------------------- 4 files changed, 3 insertions(+), 45 deletions(-) (limited to 'src/class') diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 4220c05dc..650130ab3 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 4220c05dc6b7ab7b4db33e5e05bb66be7b6c7156 +Subproject commit 650130ab312e0dc9337dc52cccf34d35875abdf7 diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index ce3d1598c..2573f5a6b 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -329,7 +329,7 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); - TU_LOG2("HID opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr); + TU_LOG2("[%u] HID opening Interface %u\r\n", dev_addr, desc_itf->bInterfaceNumber); // len = interface + hid + n*endpoints uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); diff --git a/src/host/usbh.c b/src/host/usbh.c index 520ef4c7d..c127ef310 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -792,7 +792,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) { - TU_LOG2("Open EP0 with Size = %u (addr = %u)\r\n", max_packet_size, dev_addr); + TU_LOG2("[%u] Open EP0 with Size = %u\r\n", dev_addr, max_packet_size); tusb_desc_endpoint_t ep0_desc = { diff --git a/src/portable/raspberrypi/pio/hcd_pio.c b/src/portable/raspberrypi/pio/hcd_pio.c index 4eff490c8..037ebc132 100644 --- a/src/portable/raspberrypi/pio/hcd_pio.c +++ b/src/portable/raspberrypi/pio/hcd_pio.c @@ -155,48 +155,6 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const usb_device_t *device = &usb_device[0]; return pio_usb_endpoint_open(rhport, dev_addr, (uint8_t const*) desc_ep); - -#if 0 - static uint8_t ep_id_idx; // TODO remove later - - if (ep_desc->bEndpointAddress == 0) - { - device->event = EVENT_NONE; - device->address = dev_addr; - - ep_id_idx = 0; - }else if (ep_desc->bmAttributes.xfer == TUSB_XFER_INTERRUPT) // only support interrupt endpoint - { - endpoint_t *ep = NULL; - for ( int ep_pool_idx = 0; ep_pool_idx < PIO_USB_EP_POOL_CNT; ep_pool_idx++ ) - { - if ( ep_pool[ep_pool_idx].ep_num == 0 ) - { - ep = &ep_pool[ep_pool_idx]; - device->endpoint_id[ep_id_idx] = ep_pool_idx + 1; - ep_id_idx++; - - ep->data_id = 0; - ep->ep_num = ep_desc->bEndpointAddress; - ep->interval = ep_desc->bInterval; - ep->interval_counter = 0; - ep->size = (uint8_t) tu_edpt_packet_size(ep_desc); - ep->attr = EP_ATTR_INTERRUPT; - - break; - } - } - -// TU_LOG1_INT(device->connected); -// TU_LOG1_INT(device->root); -// TU_LOG1_INT(device->is_root); -// TU_LOG1_INT(device->is_fullspeed); -// -// TU_LOG1_INT(ep_id_idx); - } - - return true; -#endif } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) -- cgit v1.3.1 From 7094ff7125b6961d52eaca0e3b8d42f3b57a1ee9 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sat, 9 Apr 2022 16:36:26 +0200 Subject: Introduce 3 fb calc options: NO_SOF_BY_USER, SOF_BY_AUDIO_D, SOF_BY_USER --- src/class/audio/audio_device.c | 82 ++++++++++++++++++++++++++++++------------ src/class/audio/audio_device.h | 70 +++++++++++++++++++++++++++++------- 2 files changed, 116 insertions(+), 36 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 434bfdcc6..2e2653e48 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -305,11 +305,12 @@ typedef struct #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#if !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value #endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value volatile uint8_t fb_n_frames_current; // Current (micro)frame number @@ -328,10 +329,15 @@ typedef struct uint64_t fb_param_factor_N; // Numerator of feedback parameter coefficient uint64_t fb_param_factor_D; // Denominator of feedback parameter coefficient #endif -#endif +#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER + volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value #endif -#endif + +#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING tu_fifo_t ep_in_ff; @@ -445,7 +451,7 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); #endif @@ -1572,6 +1578,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP usbd_edpt_close(rhport, audio->ep_fb); audio->ep_fb = 0; + audio->fb_n_frames = 0; + #endif } #endif @@ -1631,7 +1639,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif // Invoke callback - can be used to trigger data sampling if not already running -// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); // Schedule first transmit if alternate interface is not zero i.e. streaming is disabled - in case no sample data is available a ZLP is loaded // It is necessary to trigger this here since the refill is done with an RX FIFO empty interrupt which can only trigger if something was in there @@ -1665,10 +1673,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // In case of asynchronous EP, call Cb after ep_fb is set -// if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) ) -// { -// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); -// } + // if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) ) + // { + // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + // } #else // Invoke callback if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); @@ -1685,19 +1693,22 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1) // Check if usage is explicit data feedback { audio->ep_fb = ep_addr; + audio->fb_n_frames = desc_ep->bInterval; -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER)) usbd_sof_enable(rhport, true); // Enable SOF interrupt - audio->fb_n_frames = desc_ep->bInterval; +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER audio->fb_n_frames_current = 0; audio->fb_n_cycles_old = 0; #endif -// // Invoke callback after ep_out is set -// if (audio->ep_out != 0) -// { -// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); -// } + // // Invoke callback after ep_out is set + // if (audio->ep_out != 0) + // { + // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + // } } #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1721,7 +1732,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * } // Disable SOF interrupt if no driver has any enabled feedback EP -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER)) bool disable = true; @@ -2025,7 +2036,14 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 return false; } -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER)) +uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id) +{ + return _audiod_fct[func_id].fb_n_frames; +} +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) // This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as // uint8_t const itf = tu_u16_low(p_request->wIndex); @@ -2081,12 +2099,14 @@ TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_ } #endif -void audiod_sof (uint8_t rhport, uint32_t frame_count) +TU_ATTR_WEAK void audiod_sof (uint8_t rhport, uint32_t frame_count) { (void) rhport; (void) frame_count; // frame_count is not used since some devices may not provide the frame count value -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec // Boiled down, the feedback value Ff = n_samples / (micro)frame. @@ -2136,7 +2156,23 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) } } -#endif +#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) + +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) + // Iterate over audio functions and call callback function + for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) + { + audiod_function_t* audio = &_audiod_fct[i]; + + if (audio->ep_fb != 0) + { + tud_audio_sof_isr_cb(i, frame_count); + } + } + +#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) + +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP } bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_request_t const * p_request, void* data, uint16_t len) @@ -2416,7 +2452,7 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) #else bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index e5eaed9c7..e8721cf27 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -191,13 +191,24 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 #endif +// Possible options for determination of feedback value +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER 1 // Feedback value must be determined by the user itself and set by use of tud_audio_n_fb_set(). The feedback value may be determined e.g. from some fill status of some FIFO buffer. Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus less CPU load, disadvantage: typically a larger FIFO is needed to compensate for jitter (e.g. 8 frames), i.e. a larger delay is introduced. +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER 2 // Feedback value is calculated within the audio driver by use of SOF interrupt. The driver needs information about the master clock f_m from which the audio sample frequency f_s is derived, f_s itself, and the cycle count of f_m at time of the SOF interrupt (e.g. by use of a hardware counter) - see tud_audio_set_fb_params(). Advantage: Reduced jitter in the feedback value computation, hence, the receive FIFO can be smaller (e.g. 2 frames) and thus a smaller delay is possible, disadvantage: higher CPU load due to SOF ISR handling every frame i.e. 1ms or 125us. This option is a great starting point to try the SOF ISR option but depending on your hardware setup (performance of the CPU) it might not work. If so, figure out why and use the next option. (The most critical point is the reading of the cycle counter value of f_m. It is read from within the SOF ISR - see: audiod_sof() -, hence, the ISR must has a high priority such that no software dependent "random" delay i.e. jitter is introduced). +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER 3 // Feedback value is determined by the user by use of SOF interrupt. The user may use tud_audio_sof_isr_cb() which is called every SOF (of course only invoked when an alternate interface other than zero was set). The number of frames used to determine the feedback value for the currently active alternate setting can be get by tud_audio_get_fb_n_frames(). The feedback value must be set by use of tud_audio_n_fb_set(). + // Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user -#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 0 // 0 or 1 +#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER +#endif + +#ifdef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) +#error Unknown CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION. Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER! +#endif #endif // Feeback calculation mode -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT 1 #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT 2 @@ -484,6 +495,8 @@ TU_ATTR_WEAK bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_byte #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) + // This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. // // The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default, @@ -494,15 +507,16 @@ TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); // driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. // Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value. -# if !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); -# else -// This callback function is called once the feedback value needs to be updated within the SOF ISR in the audio class. To determine the feedback value, some -// parameters need to be given. The user must implement this callback function and provide the current cycle count of the master clock. -// The feedback endpoint number can be used to identify the correct audio function in case multiple audio functions were defined. -TU_ATTR_WEAK uint32_t tud_audio_n_get_fm_n_cycles_cb(uint8_t rhport, uint8_t ep_fb); +uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); +static inline uint8_t tud_audio_get_fb_n_frames(); + +#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER // f_m : Main clock frequency in Hz i.e. master clock to which sample clock is locked // f_s : Current sample rate in Hz @@ -513,10 +527,34 @@ TU_ATTR_WEAK uint32_t tud_audio_n_get_fm_n_cycles_cb(uint8_t rhport, uint8_t ep_ // uint8_t const alt = tu_u16_low(p_request->wValue); // such that tud_audio_set_fb_params() gets called with the parameters corresponding to the defined interface and alternate setting // Also, start the main clock cycle counter (or reset its value) within tud_audio_set_itf_cb() -TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count); -#endif +bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count); -#endif +#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER + +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) + +// This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. +// +// The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default, +// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set, then tinyusb +// expects 16.16 format and handles the conversion to 10.14 on FS. +// +// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the +// driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. + +// Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value. + +bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); +static inline bool tud_audio_fb_set(uint32_t feedback); + +uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); +static inline uint8_t tud_audio_get_fb_n_frames(); + +TU_ATTR_WEAK void tud_audio_sof_isr_cb(uint8_t func_id, uint32_t frame); + +#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) + +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied); @@ -657,11 +695,17 @@ static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t l } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER)) static inline bool tud_audio_fb_set(uint32_t feedback) { return tud_audio_n_fb_set(0, feedback); } + +static inline uint8_t tud_audio_get_fb_n_frames() +{ + return tud_audio_n_get_fb_n_frames(0); +} + #endif //--------------------------------------------------------------------+ -- cgit v1.3.1 From 11f0ffd9a833f4ea9b28fd12f4dff03e9bb99331 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sat, 16 Apr 2022 14:47:42 +0200 Subject: Generalize feedback value min and max --- src/class/audio/audio_device.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 2e2653e48..b0a49fb04 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -312,6 +312,8 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + uint32_t fb_val_min; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. + uint32_t fb_val_max; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value volatile uint8_t fb_n_frames_current; // Current (micro)frame number volatile uint32_t fb_n_cycles_old; // Old cycle count @@ -2094,6 +2096,9 @@ TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_ audio->fb_param_factor_D = (uint64_t)f_m * audio->fb_n_frames; #endif + audio->fb_val_min = ((TUSB_SPEED_FULL == tud_speed_get() ? (f_s/1000) : (f_s/8000)) - 1) << 16; // Minimal value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) + audio->fb_val_max = ((TUSB_SPEED_FULL == tud_speed_get() ? (f_s/1000) : (f_s/8000)) + 1) << 16; // Maximum value in 16.16 format + return true; } @@ -2139,16 +2144,18 @@ TU_ATTR_WEAK void audiod_sof (uint8_t rhport, uint32_t frame_count) feedback = ((n_cylces - audio->fb_n_cycles_old) << 3) * audio->fb_param_factor_N / audio->fb_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision #endif - // Buffer count checks ? + // For Windows: https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers + // The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1. This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot (audio slot = channel count samples). - // Magic checks - where are they from? - if (feedback > 2949166){ // 45.0007 in 16.16 format - feedback = 2949166; + if (feedback > audio->fb_val_max){ + feedback = audio->fb_val_max; } - if ( feedback < 2883630) { // 44.0007 in 16.16 format - feedback = 2883630; + if ( feedback < audio->fb_val_min) { + feedback = audio->fb_val_min; } + // Buffer count checks ? + tud_audio_n_fb_set(i, feedback); audio->fb_n_frames_current = 0; audio->fb_n_cycles_old = n_cylces; -- cgit v1.3.1 From c5ba1ea8c17a379beb47d9689e85e2ce6e67206f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 May 2022 22:54:47 +0700 Subject: changes proposal to audio feedback computation --- src/class/audio/audio_device.c | 239 +++++++++++++++++------------------------ src/class/audio/audio_device.h | 100 +++++------------ src/common/tusb_common.h | 6 -- src/device/usbd.c | 6 +- src/device/usbd.h | 2 +- 5 files changed, 129 insertions(+), 224 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index b0a49fb04..c3a252a2c 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -261,6 +261,13 @@ osal_mutex_def_t rx_supp_ff_mutex_rd_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; #endif #endif +enum { + FEEDBACK_COMPUTE_DISABLED, + FEEDBACK_COMPUTE_FLOAT, + FEEDBACK_COMPUTE_FIXED, + FEEDBACK_COMPUTE_POWER_OF_2, +}; + typedef struct { uint8_t rhport; @@ -305,38 +312,22 @@ typedef struct #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER - uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). - uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value -#endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER - volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). - uint32_t fb_val_min; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. - uint32_t fb_val_max; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. - uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value - volatile uint8_t fb_n_frames_current; // Current (micro)frame number - volatile uint32_t fb_n_cycles_old; // Old cycle count - uint32_t * fb_param_p_cycle_count; // Pointer to cycle counter + uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value + uint8_t fb_n_frames_shift; + uint8_t fb_compute_method; + + uint32_t fb_val_min; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. + uint32_t fb_val_max; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT + // should be union uint8_t fb_power_of_two_val; -#endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT float fb_float_val; -#endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT - uint64_t fb_param_factor_N; // Numerator of feedback parameter coefficient - uint64_t fb_param_factor_D; // Denominator of feedback parameter coefficient -#endif -#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER - volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). - uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value -#endif + uint32_t fb_param_factor_N; + uint32_t fb_param_factor_D; #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -453,8 +444,8 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) -static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); #endif bool tud_audio_n_mounted(uint8_t func_id) @@ -1695,16 +1686,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1) // Check if usage is explicit data feedback { audio->ep_fb = ep_addr; - audio->fb_n_frames = desc_ep->bInterval; - -#if ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER)) - usbd_sof_enable(rhport, true); // Enable SOF interrupt -#endif + audio->fb_n_frames = 1 << (desc_ep->bInterval -1); + audio->fb_n_frames_shift = desc_ep->bInterval -1; -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER - audio->fb_n_frames_current = 0; - audio->fb_n_cycles_old = 0; -#endif + // Enable SOF interrupt if callback is implemented + if (tud_audio_sof_isr) usbd_sof_enable(rhport, true); // // Invoke callback after ep_out is set // if (audio->ep_out != 0) @@ -1725,6 +1711,24 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Invoke one callback for a final set interface if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + // Prepare feedback computation if callback is available + if (tud_audio_feedback_params_cb) + { + uint32_t sample_freq = 0; + uint32_t mclk_freq = 0; + uint8_t fixed_point = 0; + tud_audio_feedback_params_cb(func_id, alt, &sample_freq, &mclk_freq, &fixed_point); + + if ( sample_freq == 0 || mclk_freq == 0 ) + { + audio->fb_compute_method = FEEDBACK_COMPUTE_DISABLED; + }else + { + audio->fb_compute_method = fixed_point ? FEEDBACK_COMPUTE_FIXED : FEEDBACK_COMPUTE_FLOAT; + set_fb_params(audio, sample_freq, mclk_freq); + } + } + // We are done - abort loop break; } @@ -1734,22 +1738,17 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * } // Disable SOF interrupt if no driver has any enabled feedback EP -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER)) - bool disable = true; - for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) { if (_audiod_fct[i].ep_fb != 0) { disable = false; + break; } } - if (disable) usbd_sof_enable(rhport, false); -#endif - tud_control_status(rhport, p_request); return true; @@ -2022,7 +2021,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 // Transmission of feedback EP finished if (_audiod_fct[func_id].ep_fb == ep_addr) { - if (tud_audio_fb_done_cb) TU_VERIFY(tud_audio_fb_done_cb(rhport)); + if (tud_audio_fb_done_cb) tud_audio_fb_done_cb(func_id); // Schedule a transmit with the new value if EP is not busy if (!usbd_edpt_busy(rhport, _audiod_fct[func_id].ep_fb)) @@ -2038,81 +2037,93 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 return false; } -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER)) +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id) { return _audiod_fct[func_id].fb_n_frames; } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -// This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as -// uint8_t const itf = tu_u16_low(p_request->wIndex); -// uint8_t const alt = tu_u16_low(p_request->wValue); -// such that tud_audio_set_fb_params() gets called with the parameters corresponding to the defined interface and alternate setting -// Also, start the main clock cycle counter (or reset its value) within tud_audio_set_itf_cb() -TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count) +static bool set_fb_params(audiod_function_t* audio, uint32_t f_s, uint32_t f_m) { - audiod_function_t* audio = &_audiod_fct[func_id]; - audio->fb_param_p_cycle_count = p_cycle_count; - // Check if frame interval is within sane limits // The interval value audio->fb_n_frames was taken from the descriptors within audiod_set_interface() - // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed - this lower limit ensures the measures feedback value has sufficient precision - if ((TUSB_SPEED_FULL == tud_speed_get() && ((2^10 * f_s / f_m) + 1) > audio->fb_n_frames) || (TUSB_SPEED_HIGH == tud_speed_get() && ((2^13 * f_s / f_m) + 1) > audio->fb_n_frames)) + // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed + // this lower limit ensures the measures feedback value has sufficient precision + uint32_t const k = (TUSB_SPEED_FULL == tud_speed_get()) ? 10 : 13; + if ( (((1UL << k) * f_s / f_m) + 1) > audio->fb_n_frames ) { - TU_LOG2(" UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false; + TU_LOG1(" UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false; } - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT // Check if parameters really allow for a power of two division - if ((f_m % f_s) != 0 || !tu_is_power_of_two(audio->fb_n_frames * f_m / f_s)) + if ((f_m % f_s) == 0 && tu_is_power_of_two(f_m / f_s)) { - TU_LOG2(" FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT not possible!\r\n"); TU_BREAKPOINT(); return false; + audio->fb_compute_method = FEEDBACK_COMPUTE_POWER_OF_2; + audio->fb_power_of_two_val = 16 - audio->fb_n_frames_shift - tu_log2(f_m / f_s); + }else if ( audio->fb_compute_method == FEEDBACK_COMPUTE_FLOAT) + { + audio->fb_float_val = (float)f_s / f_m * (1UL << (16 - audio->fb_n_frames_shift)); + }else + { + audio->fb_param_factor_N = f_s; + audio->fb_param_factor_D = f_m; } - audio->fb_power_of_two_val = 16 - tu_log2(audio->fb_n_frames * f_m / f_s); -#endif + // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) + uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; + audio->fb_val_min = (f_s/frame_div - 1) << 16; + audio->fb_val_max = (f_s/frame_div + 1) << 16; -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT - audio->fb_float_val = (float)f_s / audio->fb_n_frames / f_m * (1 << 16); + return true; +} #endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT - - // f_s max is 2^19-1 = 524287 Hz - // f_m max is 2^29/(1 ms * n_frames) for full speed and 2^29/(125 us * n_frames) for high speed, this means for f_m fitting in an uint32, n_frames must be < 125 for full speed and < 1000 for high speed (1000 does not fit into uint8 so the maximum possible value cannot even be reached by UAC2 - we don't need to check for it) +uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) +{ + audiod_function_t* audio = &_audiod_fct[func_id]; + uint32_t feedback; - if ((f_s > (2^19)-1) || (TUSB_SPEED_FULL == tud_speed_get() && (audio->fb_n_frames > 125))) + switch (audio->fb_compute_method) { - // If this check fails, not every thing is lost - you need to re-evaluate the scaling factors of the parameters such that the numbers fit into uint64 again. feedback = n_cycles * S_c / (n_frames * S_n) * f_s * S_s / (f_m * S_m). In the end S_c*S_s / (S_n * S_m) = 2^16 for a 16.16 fixed point precision. If you find something, define your own function of tud_audio_set_feedback_params_fm_fs() and audiod_sof() and use your values - TU_LOG2(" FEEDBACK_DETERMINATION_MODE_FIXED_POINT not possible!\r\n"); TU_BREAKPOINT(); return false; - } + case FEEDBACK_COMPUTE_POWER_OF_2: + feedback = cycles << audio->fb_power_of_two_val; + break; - audio->fb_param_factor_N = (uint64_t)f_s << 13; - audio->fb_param_factor_D = (uint64_t)f_m * audio->fb_n_frames; -#endif + case FEEDBACK_COMPUTE_FLOAT: + feedback = (uint32_t) ((float) cylces * audio->fb_float_val); + break; + + case FEEDBACK_COMPUTE_FIXED: + { + uint64_t fb64 = (((uint64_t) cycles) * audio->fb_param_factor_N) << (16 - audio->fb_n_frames_shift); + feedback = (uint32_t) (fb64 / audio->fb_param_factor_D); + } + break; - audio->fb_val_min = ((TUSB_SPEED_FULL == tud_speed_get() ? (f_s/1000) : (f_s/8000)) - 1) << 16; // Minimal value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) - audio->fb_val_max = ((TUSB_SPEED_FULL == tud_speed_get() ? (f_s/1000) : (f_s/8000)) + 1) << 16; // Maximum value in 16.16 format + default: return 0; + } - return true; + // For Windows: https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers + // The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1. + // This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot + // (audio slot = channel count samples). + if ( feedback > audio->fb_val_max ) feedback = audio->fb_val_max; + if ( feedback < audio->fb_val_min ) feedback = audio->fb_val_min; + + tud_audio_n_fb_set(func_id, feedback); + return feedback; } -#endif -TU_ATTR_WEAK void audiod_sof (uint8_t rhport, uint32_t frame_count) +void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) { (void) rhport; - (void) frame_count; // frame_count is not used since some devices may not provide the frame count value #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) - // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec // Boiled down, the feedback value Ff = n_samples / (micro)frame. // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) @@ -2126,59 +2137,13 @@ TU_ATTR_WEAK void audiod_sof (uint8_t rhport, uint32_t frame_count) if (audio->ep_fb != 0) { - audio->fb_n_frames_current++; - if (audio->fb_n_frames_current == audio->fb_n_frames) + uint32_t const interval = (1UL << audio->fb_n_frames); + if ( 0 == (frame_count & (interval-1)) ) { - uint32_t n_cylces = *audio->fb_param_p_cycle_count; - uint32_t feedback; - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT - feedback = (n_cylces - audio->fb_n_cycles_old) << audio->fb_power_of_two_val; -#endif - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT - feedback = (uint32_t)((float)(n_cylces - audio->fb_n_cycles_old) * audio->fb_float_val); -#endif - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT - feedback = ((n_cylces - audio->fb_n_cycles_old) << 3) * audio->fb_param_factor_N / audio->fb_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision -#endif - - // For Windows: https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers - // The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1. This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot (audio slot = channel count samples). - - if (feedback > audio->fb_val_max){ - feedback = audio->fb_val_max; - } - if ( feedback < audio->fb_val_min) { - feedback = audio->fb_val_min; - } - - // Buffer count checks ? - - tud_audio_n_fb_set(i, feedback); - audio->fb_n_frames_current = 0; - audio->fb_n_cycles_old = n_cylces; + if(tud_audio_sof_isr) tud_audio_sof_isr(i, frame_count); } } } - -#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) - -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) - // Iterate over audio functions and call callback function - for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) - { - audiod_function_t* audio = &_audiod_fct[i]; - - if (audio->ep_fb != 0) - { - tud_audio_sof_isr_cb(i, frame_count); - } - } - -#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) - #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP } @@ -2459,11 +2424,7 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER -static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) -#else bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) -#endif { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index e8721cf27..9ed7d1da4 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -191,41 +191,6 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 #endif -// Possible options for determination of feedback value -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER 1 // Feedback value must be determined by the user itself and set by use of tud_audio_n_fb_set(). The feedback value may be determined e.g. from some fill status of some FIFO buffer. Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus less CPU load, disadvantage: typically a larger FIFO is needed to compensate for jitter (e.g. 8 frames), i.e. a larger delay is introduced. -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER 2 // Feedback value is calculated within the audio driver by use of SOF interrupt. The driver needs information about the master clock f_m from which the audio sample frequency f_s is derived, f_s itself, and the cycle count of f_m at time of the SOF interrupt (e.g. by use of a hardware counter) - see tud_audio_set_fb_params(). Advantage: Reduced jitter in the feedback value computation, hence, the receive FIFO can be smaller (e.g. 2 frames) and thus a smaller delay is possible, disadvantage: higher CPU load due to SOF ISR handling every frame i.e. 1ms or 125us. This option is a great starting point to try the SOF ISR option but depending on your hardware setup (performance of the CPU) it might not work. If so, figure out why and use the next option. (The most critical point is the reading of the cycle counter value of f_m. It is read from within the SOF ISR - see: audiod_sof() -, hence, the ISR must has a high priority such that no software dependent "random" delay i.e. jitter is introduced). -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER 3 // Feedback value is determined by the user by use of SOF interrupt. The user may use tud_audio_sof_isr_cb() which is called every SOF (of course only invoked when an alternate interface other than zero was set). The number of frames used to determine the feedback value for the currently active alternate setting can be get by tud_audio_get_fb_n_frames(). The feedback value must be set by use of tud_audio_n_fb_set(). - -// Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user -#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER -#endif - -#ifdef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) -#error Unknown CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION. Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER! -#endif -#endif - -// Feeback calculation mode -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER - -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT 1 -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT 2 -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT 3 - -#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE -#error You must tell the driver the feedback determination mode! Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT! -#endif - -#ifdef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT) -#error Unknown CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE. Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT! -#endif -#endif - -#endif - // Audio interrupt control EP size - disabled if 0 #ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN #define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) @@ -493,45 +458,14 @@ TU_ATTR_WEAK bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_byte #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); - -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) - -// This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. -// -// The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default, -// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set, then tinyusb -// expects 16.16 format and handles the conversion to 10.14 on FS. -// -// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the -// driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. - -// Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value. - -bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); -static inline bool tud_audio_fb_set(uint32_t feedback); +TU_ATTR_WEAK void tud_audio_fb_done_cb(uint8_t func_id); -uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); -static inline uint8_t tud_audio_get_fb_n_frames(); - -#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER - -// f_m : Main clock frequency in Hz i.e. master clock to which sample clock is locked -// f_s : Current sample rate in Hz -// p_cycle_count : Pointer to main clock cycle counter register where the current count can be read from (e.g. a timer register) -// This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as -// uint8_t const itf = tu_u16_low(p_request->wIndex); -// uint8_t const alt = tu_u16_low(p_request->wValue); -// such that tud_audio_set_fb_params() gets called with the parameters corresponding to the defined interface and alternate setting -// Also, start the main clock cycle counter (or reset its value) within tud_audio_set_itf_cb() -bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count); +// determined by the user itself and set by use of tud_audio_n_fb_set(). The feedback value may be determined e.g. from some fill status of some FIFO buffer. Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus less CPU load, disadvantage: typically a larger FIFO is needed to compensate for jitter (e.g. 8 frames), i.e. a larger delay is introduced. -#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER +// Feedback value is calculated within the audio driver by use of SOF interrupt. The driver needs information about the master clock f_m from which the audio sample frequency f_s is derived, f_s itself, and the cycle count of f_m at time of the SOF interrupt (e.g. by use of a hardware counter) - see tud_audio_set_fb_params(). Advantage: Reduced jitter in the feedback value computation, hence, the receive FIFO can be smaller (e.g. 2 frames) and thus a smaller delay is possible, disadvantage: higher CPU load due to SOF ISR handling every frame i.e. 1ms or 125us. This option is a great starting point to try the SOF ISR option but depending on your hardware setup (performance of the CPU) it might not work. If so, figure out why and use the next option. (The most critical point is the reading of the cycle counter value of f_m. It is read from within the SOF ISR - see: audiod_sof() -, hence, the ISR must has a high priority such that no software dependent "random" delay i.e. jitter is introduced). -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) +// Feedback value is determined by the user by use of SOF interrupt. The user may use tud_audio_sof_isr() which is called every SOF (of course only invoked when an alternate interface other than zero was set). The number of frames used to determine the feedback value for the currently active alternate setting can be get by tud_audio_get_fb_n_frames(). The feedback value must be set by use of tud_audio_n_fb_set(). // This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. // @@ -539,20 +473,35 @@ bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32 // the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set, then tinyusb // expects 16.16 format and handles the conversion to 10.14 on FS. // -// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the +// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the // driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. // Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value. +// Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec +// Boiled down, the feedback value Ff = n_samples / (micro)frame. +// Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) +// The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_m / f_s)), K) +// feedback = n_cycles / n_frames * f_s / f_m in 16.16 format, where n_cycles are the number of main clock cycles within fb_n_frames + bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); static inline uint8_t tud_audio_get_fb_n_frames(); -TU_ATTR_WEAK void tud_audio_sof_isr_cb(uint8_t func_id, uint32_t frame); +// Update feedback value with passed cycles since last time this update function is called. +// Typically called within tud_audio_sof_isr(). Required tud_audio_feedback_params_cb() is implemented +// This function will also call tud_audio_feedback_set() +// return feedback value in 16.16 for reference (0 for error) +uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles); + +// mclk_freq : Main clock frequency in Hz i.e. master clock to which sample clock is locked +// sample_freq : sample frequency in Hz +// fixed_point : 0 float (default), 1 fixed point (for mcu without FPU) +TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, uint32_t* sample_freq, uint32_t* mclk_freq, uint8_t* fixed_point); -#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) +TU_ATTR_WEAK void tud_audio_sof_isr(uint8_t func_id, uint32_t frame); #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP @@ -695,7 +644,8 @@ static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t l } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER)) +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + static inline bool tud_audio_fb_set(uint32_t feedback) { return tud_audio_n_fb_set(0, feedback); @@ -716,7 +666,7 @@ void audiod_reset (uint8_t rhport); uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool audiod_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); -void audiod_sof (uint8_t rhport, uint32_t frame_count); +void audiod_sof_isr (uint8_t rhport, uint32_t frame_count); #ifdef __cplusplus } diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index bcdf8933a..b1ee40a1a 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -134,12 +134,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_offset4k(uint32_t value) { retur //------------- Mathematics -------------// TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return (v + d -1)/d; } -/// inclusive range checking TODO remove -TU_ATTR_ALWAYS_INLINE static inline bool tu_within(uint32_t lower, uint32_t value, uint32_t upper) -{ - return (lower <= value) && (value <= upper); -} - // log2 of a value is its MSB's position // TODO use clz TODO remove static inline uint8_t tu_log2(uint32_t value) diff --git a/src/device/usbd.c b/src/device/usbd.c index 8ab67c8de..b32cee813 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -69,7 +69,7 @@ typedef struct volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; - uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) + uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each tu_edpt_state_t ep_status[CFG_TUD_ENDPPOINT_MAX][2]; @@ -134,7 +134,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = audiod_open, .control_xfer_cb = audiod_control_xfer_cb, .xfer_cb = audiod_xfer_cb, - .sof_isr = audiod_sof + .sof_isr = audiod_sof_isr }, #endif @@ -170,7 +170,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = vendord_open, .control_xfer_cb = tud_vendor_control_xfer_cb, .xfer_cb = vendord_xfer_cb, - .sof_isr = NULL + .sof_isr = NULL }, #endif diff --git a/src/device/usbd.h b/src/device/usbd.h index d485d8711..30a27c5ee 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -33,7 +33,7 @@ extern "C" { #endif -typedef void (*tud_sof_isr_t) (uint32_t frame_count); +// typedef void (*tud_sof_isr_t) (uint32_t frame_count); //--------------------------------------------------------------------+ // Application API -- cgit v1.3.1 From 20b810d25b60f3ab1b2ec58186bbb739b6b5c9b7 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 May 2022 23:01:06 +0700 Subject: fix ci build --- src/class/audio/audio_device.c | 7 ++++++- src/class/audio/audio_device.h | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index c3a252a2c..a81ddc53e 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1708,6 +1708,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * TU_VERIFY(foundEPs == nEps); +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Invoke one callback for a final set interface if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); @@ -1728,6 +1729,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * set_fb_params(audio, sample_freq, mclk_freq); } } +#endif // We are done - abort loop break; @@ -1737,6 +1739,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * p_desc = tu_desc_next(p_desc); } +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Disable SOF interrupt if no driver has any enabled feedback EP bool disable = true; for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) @@ -1748,6 +1751,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * } } if (disable) usbd_sof_enable(rhport, false); +#endif tud_control_status(rhport, p_request); @@ -2080,7 +2084,6 @@ static bool set_fb_params(audiod_function_t* audio, uint32_t f_s, uint32_t f_m) return true; } -#endif uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) { @@ -2118,10 +2121,12 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) return feedback; } +#endif void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) { (void) rhport; + (void) frame_count; #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 9ed7d1da4..22394aaca 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -490,6 +490,8 @@ static inline bool tud_audio_fb_set(uint32_t feedback); uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); static inline uint8_t tud_audio_get_fb_n_frames(); +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + // Update feedback value with passed cycles since last time this update function is called. // Typically called within tud_audio_sof_isr(). Required tud_audio_feedback_params_cb() is implemented // This function will also call tud_audio_feedback_set() @@ -503,7 +505,6 @@ TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, TU_ATTR_WEAK void tud_audio_sof_isr(uint8_t func_id, uint32_t frame); -#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied); -- cgit v1.3.1 From 5766c9ac4ed3525b3223ad0751f871b08a1bb5fb Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 19 May 2022 13:44:10 +0700 Subject: rename tud_audio_sof_isr() to tud_audio_feedback_interval_isr() - also add interval_log2 to isr callback - also rename other variables --- src/class/audio/audio_device.c | 37 +++++++++++++++++++------------------ src/class/audio/audio_device.h | 4 +++- 2 files changed, 22 insertions(+), 19 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a81ddc53e..db8bbb819 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -326,8 +326,8 @@ typedef struct float fb_float_val; - uint32_t fb_param_factor_N; - uint32_t fb_param_factor_D; + uint32_t fb_sample_freq; + uint32_t fb_mclk_freq; #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1686,11 +1686,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1) // Check if usage is explicit data feedback { audio->ep_fb = ep_addr; - audio->fb_n_frames = 1 << (desc_ep->bInterval -1); + audio->fb_n_frames = 1U << (desc_ep->bInterval -1); // TODO correctly set USB frame interval for SOF (not micro-frame) audio->fb_n_frames_shift = desc_ep->bInterval -1; // Enable SOF interrupt if callback is implemented - if (tud_audio_sof_isr) usbd_sof_enable(rhport, true); + if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true); // // Invoke callback after ep_out is set // if (audio->ep_out != 0) @@ -2050,7 +2050,7 @@ uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id) #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -static bool set_fb_params(audiod_function_t* audio, uint32_t f_s, uint32_t f_m) +static bool set_fb_params(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq) { // Check if frame interval is within sane limits // The interval value audio->fb_n_frames was taken from the descriptors within audiod_set_interface() @@ -2058,29 +2058,29 @@ static bool set_fb_params(audiod_function_t* audio, uint32_t f_s, uint32_t f_m) // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed // this lower limit ensures the measures feedback value has sufficient precision uint32_t const k = (TUSB_SPEED_FULL == tud_speed_get()) ? 10 : 13; - if ( (((1UL << k) * f_s / f_m) + 1) > audio->fb_n_frames ) + if ( (((1UL << k) * sample_freq / mclk_freq) + 1) > audio->fb_n_frames ) { TU_LOG1(" UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false; } // Check if parameters really allow for a power of two division - if ((f_m % f_s) == 0 && tu_is_power_of_two(f_m / f_s)) + if ((mclk_freq % sample_freq) == 0 && tu_is_power_of_two(mclk_freq / sample_freq)) { audio->fb_compute_method = FEEDBACK_COMPUTE_POWER_OF_2; - audio->fb_power_of_two_val = 16 - audio->fb_n_frames_shift - tu_log2(f_m / f_s); + audio->fb_power_of_two_val = 16 - audio->fb_n_frames_shift - tu_log2(mclk_freq / sample_freq); }else if ( audio->fb_compute_method == FEEDBACK_COMPUTE_FLOAT) { - audio->fb_float_val = (float)f_s / f_m * (1UL << (16 - audio->fb_n_frames_shift)); + audio->fb_float_val = (float)sample_freq / mclk_freq * (1UL << (16 - audio->fb_n_frames_shift)); }else { - audio->fb_param_factor_N = f_s; - audio->fb_param_factor_D = f_m; + audio->fb_sample_freq = sample_freq; + audio->fb_mclk_freq = mclk_freq; } // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; - audio->fb_val_min = (f_s/frame_div - 1) << 16; - audio->fb_val_max = (f_s/frame_div + 1) << 16; + audio->fb_val_min = (sample_freq/frame_div - 1) << 16; + audio->fb_val_max = (sample_freq/frame_div + 1) << 16; return true; } @@ -2093,7 +2093,7 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) switch (audio->fb_compute_method) { case FEEDBACK_COMPUTE_POWER_OF_2: - feedback = cycles << audio->fb_power_of_two_val; + feedback = (cycles << audio->fb_power_of_two_val); break; case FEEDBACK_COMPUTE_FLOAT: @@ -2102,8 +2102,8 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) case FEEDBACK_COMPUTE_FIXED: { - uint64_t fb64 = (((uint64_t) cycles) * audio->fb_param_factor_N) << (16 - audio->fb_n_frames_shift); - feedback = (uint32_t) (fb64 / audio->fb_param_factor_D); + uint64_t fb64 = (((uint64_t) cycles) * audio->fb_sample_freq) << (16 - audio->fb_n_frames_shift); + feedback = (uint32_t) (fb64 / audio->fb_mclk_freq); } break; @@ -2142,10 +2142,11 @@ void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) if (audio->ep_fb != 0) { - uint32_t const interval = (1UL << audio->fb_n_frames); + // TODO hs need to be adjusted to frame (SOF event is not generated for micro-frame) + uint32_t const interval = (1UL << audio->fb_n_frames_shift); if ( 0 == (frame_count & (interval-1)) ) { - if(tud_audio_sof_isr) tud_audio_sof_isr(i, frame_count); + if(tud_audio_feedback_interval_isr) tud_audio_feedback_interval_isr(i, frame_count, audio->fb_n_frames_shift); } } } diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 22394aaca..e6d3b74e6 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -503,7 +503,9 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles); // fixed_point : 0 float (default), 1 fixed point (for mcu without FPU) TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, uint32_t* sample_freq, uint32_t* mclk_freq, uint8_t* fixed_point); -TU_ATTR_WEAK void tud_audio_sof_isr(uint8_t func_id, uint32_t frame); +// Callback in ISR context, invoked periodically according to feedback endpoint bInterval. +// Could be used to compute and update feedback value +TU_ATTR_WEAK void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_log2); #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN -- cgit v1.3.1 From e5113a1cfc25c0e5e7e75c2644ed91d252391c28 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 19 May 2022 16:05:55 +0700 Subject: prototype for feedback method --- src/class/audio/audio_device.c | 21 +++++++-------------- src/class/audio/audio_device.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 14 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index db8bbb819..1dce6a664 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -261,13 +261,6 @@ osal_mutex_def_t rx_supp_ff_mutex_rd_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; #endif #endif -enum { - FEEDBACK_COMPUTE_DISABLED, - FEEDBACK_COMPUTE_FLOAT, - FEEDBACK_COMPUTE_FIXED, - FEEDBACK_COMPUTE_POWER_OF_2, -}; - typedef struct { uint8_t rhport; @@ -1722,10 +1715,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if ( sample_freq == 0 || mclk_freq == 0 ) { - audio->fb_compute_method = FEEDBACK_COMPUTE_DISABLED; + audio->fb_compute_method = AUDIO_FEEDBACK_METHOD_DISABLED; }else { - audio->fb_compute_method = fixed_point ? FEEDBACK_COMPUTE_FIXED : FEEDBACK_COMPUTE_FLOAT; + audio->fb_compute_method = fixed_point ? AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED : AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT; set_fb_params(audio, sample_freq, mclk_freq); } } @@ -2066,9 +2059,9 @@ static bool set_fb_params(audiod_function_t* audio, uint32_t sample_freq, uint32 // Check if parameters really allow for a power of two division if ((mclk_freq % sample_freq) == 0 && tu_is_power_of_two(mclk_freq / sample_freq)) { - audio->fb_compute_method = FEEDBACK_COMPUTE_POWER_OF_2; + audio->fb_compute_method = AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2; audio->fb_power_of_two_val = 16 - audio->fb_n_frames_shift - tu_log2(mclk_freq / sample_freq); - }else if ( audio->fb_compute_method == FEEDBACK_COMPUTE_FLOAT) + }else if ( audio->fb_compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT) { audio->fb_float_val = (float)sample_freq / mclk_freq * (1UL << (16 - audio->fb_n_frames_shift)); }else @@ -2092,15 +2085,15 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) switch (audio->fb_compute_method) { - case FEEDBACK_COMPUTE_POWER_OF_2: + case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: feedback = (cycles << audio->fb_power_of_two_val); break; - case FEEDBACK_COMPUTE_FLOAT: + case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: feedback = (uint32_t) ((float) cylces * audio->fb_float_val); break; - case FEEDBACK_COMPUTE_FIXED: + case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: { uint64_t fb64 = (((uint64_t) cycles) * audio->fb_sample_freq) << (16 - audio->fb_n_frames_shift); feedback = (uint32_t) (fb64 / audio->fb_mclk_freq); diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index e6d3b74e6..da4a45eee 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -498,6 +498,34 @@ static inline uint8_t tud_audio_get_fb_n_frames(); // return feedback value in 16.16 for reference (0 for error) uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles); +enum { + AUDIO_FEEDBACK_METHOD_DISABLED, + AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED, + AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT, + AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2, + AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FIXED, + AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FLOAT +}; + +typedef struct { + uint8_t method; + union { + struct { + uint32_t sample_freq; + uint32_t mclk_freq; + }frequency; + + struct { + uint32_t nominal; + uint32_t threshold; + // variation etc .. + }fifo_count; + }; +}audio_feedback_params_t; + + +// TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); + // mclk_freq : Main clock frequency in Hz i.e. master clock to which sample clock is locked // sample_freq : sample frequency in Hz // fixed_point : 0 float (default), 1 fixed point (for mcu without FPU) -- cgit v1.3.1 From 15aa593790311d6e279f01ba764a1a96d282a78b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 May 2022 12:27:31 +0700 Subject: wrap feedback and compute to its own struct/union --- src/class/audio/audio_device.c | 132 ++++++++++++++++++++++------------------- src/class/audio/audio_device.h | 28 +++------ 2 files changed, 78 insertions(+), 82 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 1dce6a664..e967e8c3f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -306,21 +306,29 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). - uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value - uint8_t fb_n_frames_shift; - uint8_t fb_compute_method; + struct { + uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). + uint32_t min_value; // min value according to UAC2 FMT-2.0 section 2.3.1.1. + uint32_t max_value; // max value according to UAC2 FMT-2.0 section 2.3.1.1. - uint32_t fb_val_min; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. - uint32_t fb_val_max; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. + uint8_t frame_shift; // bInterval-1 in unit of frame (FS), micro-frame (HS) + uint8_t compute_method; - // should be union - uint8_t fb_power_of_two_val; + union { + uint8_t power_of_2; // pre-computed power of 2 shift + float float_const; // pre-computed float constant - float fb_float_val; + struct { + uint32_t sample_freq; + uint32_t mclk_freq; + }fixed; - uint32_t fb_sample_freq; - uint32_t fb_mclk_freq; +// struct { +// +// }fifo_count; + }compute; + + } feedback; #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -437,10 +445,6 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); -#endif - bool tud_audio_n_mounted(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO); @@ -1059,7 +1063,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP static inline bool audiod_fb_send(uint8_t rhport, audiod_function_t *audio) { - return usbd_edpt_xfer(rhport, audio->ep_fb, (uint8_t *) &audio->fb_val, 4); + return usbd_edpt_xfer(rhport, audio->ep_fb, (uint8_t *) &audio->feedback.value, 4); } #endif @@ -1564,8 +1568,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP usbd_edpt_close(rhport, audio->ep_fb); audio->ep_fb = 0; - audio->fb_n_frames = 0; - + tu_memclr(&audio->feedback, sizeof(audio->feedback)); #endif } #endif @@ -1679,8 +1682,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1) // Check if usage is explicit data feedback { audio->ep_fb = ep_addr; - audio->fb_n_frames = 1U << (desc_ep->bInterval -1); // TODO correctly set USB frame interval for SOF (not micro-frame) - audio->fb_n_frames_shift = desc_ep->bInterval -1; + audio->feedback.frame_shift = desc_ep->bInterval -1; // Enable SOF interrupt if callback is implemented if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true); @@ -1708,18 +1710,26 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Prepare feedback computation if callback is available if (tud_audio_feedback_params_cb) { - uint32_t sample_freq = 0; - uint32_t mclk_freq = 0; - uint8_t fixed_point = 0; - tud_audio_feedback_params_cb(func_id, alt, &sample_freq, &mclk_freq, &fixed_point); + audio_feedback_params_t fb_param; - if ( sample_freq == 0 || mclk_freq == 0 ) - { - audio->fb_compute_method = AUDIO_FEEDBACK_METHOD_DISABLED; - }else + tud_audio_feedback_params_cb(func_id, alt, &fb_param); + audio->feedback.compute_method = fb_param.method; + + switch(fb_param.method) { - audio->fb_compute_method = fixed_point ? AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED : AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT; - set_fb_params(audio, sample_freq, mclk_freq); + case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: + case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: + case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: + set_fb_params_freq(audio, fb_param.frequency.sample_freq, fb_param.frequency.mclk_freq); + break; + + case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FIXED: + case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FLOAT: + // TODO feedback by fifo count + break; + + // nothing to do + default: break; } } #endif @@ -2034,24 +2044,19 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 return false; } -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id) -{ - return _audiod_fct[func_id].fb_n_frames; -} -#endif - #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -static bool set_fb_params(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq) +static bool set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq) { // Check if frame interval is within sane limits - // The interval value audio->fb_n_frames was taken from the descriptors within audiod_set_interface() + // The interval value n_frames was taken from the descriptors within audiod_set_interface() // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed // this lower limit ensures the measures feedback value has sufficient precision uint32_t const k = (TUSB_SPEED_FULL == tud_speed_get()) ? 10 : 13; - if ( (((1UL << k) * sample_freq / mclk_freq) + 1) > audio->fb_n_frames ) + uint32_t const n_frame = (1UL << audio->feedback.frame_shift); + + if ( (((1UL << k) * sample_freq / mclk_freq) + 1) > n_frame ) { TU_LOG1(" UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false; } @@ -2059,21 +2064,23 @@ static bool set_fb_params(audiod_function_t* audio, uint32_t sample_freq, uint32 // Check if parameters really allow for a power of two division if ((mclk_freq % sample_freq) == 0 && tu_is_power_of_two(mclk_freq / sample_freq)) { - audio->fb_compute_method = AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2; - audio->fb_power_of_two_val = 16 - audio->fb_n_frames_shift - tu_log2(mclk_freq / sample_freq); - }else if ( audio->fb_compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT) + audio->feedback.compute_method = AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2; + audio->feedback.compute.power_of_2 = 16 - audio->feedback.frame_shift - tu_log2(mclk_freq / sample_freq); + } + else if ( audio->feedback.compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT) { - audio->fb_float_val = (float)sample_freq / mclk_freq * (1UL << (16 - audio->fb_n_frames_shift)); - }else + audio->feedback.compute.float_const = (float)sample_freq / mclk_freq * (1UL << (16 - audio->feedback.frame_shift)); + } + else { - audio->fb_sample_freq = sample_freq; - audio->fb_mclk_freq = mclk_freq; + audio->feedback.compute.fixed.sample_freq = sample_freq; + audio->feedback.compute.fixed.mclk_freq = mclk_freq; } // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) - uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; - audio->fb_val_min = (sample_freq/frame_div - 1) << 16; - audio->fb_val_max = (sample_freq/frame_div + 1) << 16; + uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; + audio->feedback.min_value = (sample_freq/frame_div - 1) << 16; + audio->feedback.max_value = (sample_freq/frame_div + 1) << 16; return true; } @@ -2083,20 +2090,20 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) audiod_function_t* audio = &_audiod_fct[func_id]; uint32_t feedback; - switch (audio->fb_compute_method) + switch (audio->feedback.compute_method) { case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: - feedback = (cycles << audio->fb_power_of_two_val); + feedback = (cycles << audio->feedback.compute.power_of_2); break; case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: - feedback = (uint32_t) ((float) cylces * audio->fb_float_val); + feedback = (uint32_t) ((float) cycles * audio->feedback.compute.float_const); break; case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: { - uint64_t fb64 = (((uint64_t) cycles) * audio->fb_sample_freq) << (16 - audio->fb_n_frames_shift); - feedback = (uint32_t) (fb64 / audio->fb_mclk_freq); + uint64_t fb64 = (((uint64_t) cycles) * audio->feedback.compute.fixed.sample_freq) << (16 - audio->feedback.frame_shift); + feedback = (uint32_t) (fb64 / audio->feedback.compute.fixed.mclk_freq); } break; @@ -2107,8 +2114,8 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) // The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1. // This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot // (audio slot = channel count samples). - if ( feedback > audio->fb_val_max ) feedback = audio->fb_val_max; - if ( feedback < audio->fb_val_min ) feedback = audio->fb_val_min; + if ( feedback > audio->feedback.max_value ) feedback = audio->feedback.max_value; + if ( feedback < audio->feedback.min_value ) feedback = audio->feedback.min_value; tud_audio_n_fb_set(func_id, feedback); @@ -2135,11 +2142,12 @@ void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) if (audio->ep_fb != 0) { - // TODO hs need to be adjusted to frame (SOF event is not generated for micro-frame) - uint32_t const interval = (1UL << audio->fb_n_frames_shift); + // HS shift need to be adjusted since SOF event is generated for frame only + uint8_t const hs_adjust = (TUSB_SPEED_HIGH == tud_speed_get()) ? 3 : 0; + uint32_t const interval = 1UL << (audio->feedback.frame_shift - hs_adjust); if ( 0 == (frame_count & (interval-1)) ) { - if(tud_audio_feedback_interval_isr) tud_audio_feedback_interval_isr(i, frame_count, audio->fb_n_frames_shift); + if(tud_audio_feedback_interval_isr) tud_audio_feedback_interval_isr(i, frame_count, audio->feedback.frame_shift); } } } @@ -2431,7 +2439,7 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION if ( TUSB_SPEED_FULL == tud_speed_get() ) { - uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; + uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].feedback.value; // For FS format is 10.14 *(fb++) = (feedback >> 2) & 0xFF; @@ -2443,7 +2451,7 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) #else { // Send value as-is, caller will choose the appropriate format - _audiod_fct[func_id].fb_val = feedback; + _audiod_fct[func_id].feedback.value = feedback; } #endif diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index da4a45eee..09de8e9a8 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -487,11 +487,6 @@ TU_ATTR_WEAK void tud_audio_fb_done_cb(uint8_t func_id); bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); -uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); -static inline uint8_t tud_audio_get_fb_n_frames(); - -#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - // Update feedback value with passed cycles since last time this update function is called. // Typically called within tud_audio_sof_isr(). Required tud_audio_feedback_params_cb() is implemented // This function will also call tud_audio_feedback_set() @@ -511,8 +506,8 @@ typedef struct { uint8_t method; union { struct { - uint32_t sample_freq; - uint32_t mclk_freq; + uint32_t sample_freq; // sample frequency in Hz + uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on }frequency; struct { @@ -523,18 +518,16 @@ typedef struct { }; }audio_feedback_params_t; - -// TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); - -// mclk_freq : Main clock frequency in Hz i.e. master clock to which sample clock is locked -// sample_freq : sample frequency in Hz -// fixed_point : 0 float (default), 1 fixed point (for mcu without FPU) -TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, uint32_t* sample_freq, uint32_t* mclk_freq, uint8_t* fixed_point); +// Invoked when needed to set feedback parameters +TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); // Callback in ISR context, invoked periodically according to feedback endpoint bInterval. // Could be used to compute and update feedback value -TU_ATTR_WEAK void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_log2); +// frame_number : current SOF count +// interval_shift: number of bit shift i.e log2(interval) from Feedback endpoint descriptor +TU_ATTR_WEAK void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift); +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied); @@ -682,11 +675,6 @@ static inline bool tud_audio_fb_set(uint32_t feedback) return tud_audio_n_fb_set(0, feedback); } -static inline uint8_t tud_audio_get_fb_n_frames() -{ - return tud_audio_n_get_fb_n_frames(0); -} - #endif //--------------------------------------------------------------------+ -- cgit v1.3.1 From dce2ad4ffb33fe884429e0c241b1957b3cd6c453 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 May 2022 23:11:25 +0700 Subject: adding feedback fifo count (WIP) --- src/class/audio/audio_device.c | 47 ++++++++++++++++++++++++------------------ src/class/audio/audio_device.h | 9 ++++---- 2 files changed, 31 insertions(+), 25 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index e967e8c3f..31851e00c 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -323,9 +323,10 @@ typedef struct uint32_t mclk_freq; }fixed; -// struct { -// -// }fifo_count; + struct { + uint32_t nominal_value; + uint32_t threshold_bytes; + }fifo_count; }compute; } feedback; @@ -1715,17 +1716,28 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * tud_audio_feedback_params_cb(func_id, alt, &fb_param); audio->feedback.compute_method = fb_param.method; + // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) + uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; + audio->feedback.min_value = (fb_param.sample_freq/frame_div - 1) << 16; + audio->feedback.max_value = (fb_param.sample_freq/frame_div + 1) << 16; + switch(fb_param.method) { case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: - set_fb_params_freq(audio, fb_param.frequency.sample_freq, fb_param.frequency.mclk_freq); + set_fb_params_freq(audio, fb_param.sample_freq, fb_param.frequency.mclk_freq); break; case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FIXED: case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FLOAT: - // TODO feedback by fifo count + { + uint64_t fb64 = ((uint64_t) fb_param.sample_freq) << 16; + audio->feedback.compute.fifo_count.nominal_value = (uint32_t) (fb64 / frame_div); + audio->feedback.compute.fifo_count.threshold_bytes = fb_param.fifo_count.threshold_bytes; + + tud_audio_fb_set(audio->feedback.compute.fifo_count.nominal_value); + } break; // nothing to do @@ -1972,14 +1984,14 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 (void) xferred_bytes; // Search for interface belonging to given end point address and proceed as required - uint8_t func_id; - for (func_id = 0; func_id < CFG_TUD_AUDIO; func_id++) + for (uint8_t func_id = 0; func_id < CFG_TUD_AUDIO; func_id++) { + audiod_function_t* audio = &_audiod_fct[func_id]; #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN // Data transmission of control interrupt finished - if (_audiod_fct[func_id].ep_int_ctr == ep_addr) + if (audio->ep_int_ctr == ep_addr) { // According to USB2 specification, maximum payload of interrupt EP is 8 bytes on low speed, 64 bytes on full speed, and 1024 bytes on high speed (but only if an alternate interface other than 0 is used - see specification p. 49) // In case there is nothing to send we have to return a NAK - this is taken care of by PHY ??? @@ -1996,7 +2008,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 #if CFG_TUD_AUDIO_ENABLE_EP_IN // Data transmission of audio packet finished - if (_audiod_fct[func_id].ep_in == ep_addr && _audiod_fct[func_id].alt_setting != 0) + if (audio->ep_in == ep_addr && audio->alt_setting != 0) { // USB 2.0, section 5.6.4, third paragraph, states "An isochronous endpoint must specify its required bus access period. However, an isochronous endpoint must be prepared to handle poll rates faster than the one specified." // That paragraph goes on to say "An isochronous IN endpoint must return a zero-length packet whenever data is requested at a faster interval than the specified interval and data is not available." @@ -2007,7 +2019,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 // This is the only place where we can fill something into the EPs buffer! // Load new data - TU_VERIFY(audiod_tx_done_cb(rhport, &_audiod_fct[func_id])); + TU_VERIFY(audiod_tx_done_cb(rhport, audio)); // Transmission of ZLP is done by audiod_tx_done_cb() return true; @@ -2017,24 +2029,24 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 #if CFG_TUD_AUDIO_ENABLE_EP_OUT // New audio packet received - if (_audiod_fct[func_id].ep_out == ep_addr) + if (audio->ep_out == ep_addr) { - TU_VERIFY(audiod_rx_done_cb(rhport, &_audiod_fct[func_id], (uint16_t) xferred_bytes)); + TU_VERIFY(audiod_rx_done_cb(rhport, audio, (uint16_t) xferred_bytes)); return true; } #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Transmission of feedback EP finished - if (_audiod_fct[func_id].ep_fb == ep_addr) + if (audio->ep_fb == ep_addr) { if (tud_audio_fb_done_cb) tud_audio_fb_done_cb(func_id); // Schedule a transmit with the new value if EP is not busy - if (!usbd_edpt_busy(rhport, _audiod_fct[func_id].ep_fb)) + if (!usbd_edpt_busy(rhport, audio->ep_fb)) { // Schedule next transmission - value is changed bytud_audio_n_fb_set() in the meantime or the old value gets sent - return audiod_fb_send(rhport, &_audiod_fct[func_id]); + return audiod_fb_send(rhport, audio); } } #endif @@ -2077,11 +2089,6 @@ static bool set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, u audio->feedback.compute.fixed.mclk_freq = mclk_freq; } - // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) - uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; - audio->feedback.min_value = (sample_freq/frame_div - 1) << 16; - audio->feedback.max_value = (sample_freq/frame_div + 1) << 16; - return true; } diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 09de8e9a8..c44b4cc30 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -504,16 +504,15 @@ enum { typedef struct { uint8_t method; + uint32_t sample_freq; // sample frequency in Hz + union { struct { - uint32_t sample_freq; // sample frequency in Hz - uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on + uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on }frequency; struct { - uint32_t nominal; - uint32_t threshold; - // variation etc .. + uint32_t threshold_bytes; // minimum number of bytes received to be considered as filled/ready }fifo_count; }; }audio_feedback_params_t; -- cgit v1.3.1 From f2926670cc4e495e025b0838fed5b44d27e4cd43 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 31 May 2022 20:26:37 +0700 Subject: comment out fifo count method for now --- src/class/audio/audio_device.c | 18 ++++++++++-------- src/class/audio/audio_device.h | 7 +++++-- 2 files changed, 15 insertions(+), 10 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 31851e00c..01a42f34f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -305,13 +305,12 @@ typedef struct #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - struct { - uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). - uint32_t min_value; // min value according to UAC2 FMT-2.0 section 2.3.1.1. - uint32_t max_value; // max value according to UAC2 FMT-2.0 section 2.3.1.1. + uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). + uint32_t min_value; // min value according to UAC2 FMT-2.0 section 2.3.1.1. + uint32_t max_value; // max value according to UAC2 FMT-2.0 section 2.3.1.1. - uint8_t frame_shift; // bInterval-1 in unit of frame (FS), micro-frame (HS) + uint8_t frame_shift; // bInterval-1 in unit of frame (FS), micro-frame (HS) uint8_t compute_method; union { @@ -323,15 +322,17 @@ typedef struct uint32_t mclk_freq; }fixed; +#if 0 // implement later struct { uint32_t nominal_value; uint32_t threshold_bytes; }fifo_count; +#endif }compute; } feedback; - #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING @@ -1729,8 +1730,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * set_fb_params_freq(audio, fb_param.sample_freq, fb_param.frequency.mclk_freq); break; - case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FIXED: - case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FLOAT: + #if 0 // implement later + case AUDIO_FEEDBACK_METHOD_FIFO_COUNT: { uint64_t fb64 = ((uint64_t) fb_param.sample_freq) << 16; audio->feedback.compute.fifo_count.nominal_value = (uint32_t) (fb64 / frame_div); @@ -1739,6 +1740,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * tud_audio_fb_set(audio->feedback.compute.fifo_count.nominal_value); } break; + #endif // nothing to do default: break; diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index c44b4cc30..13f24fb62 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -498,8 +498,9 @@ enum { AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED, AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT, AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2, - AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FIXED, - AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FLOAT + + // impelemnt later + // AUDIO_FEEDBACK_METHOD_FIFO_COUNT }; typedef struct { @@ -511,9 +512,11 @@ typedef struct { uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on }frequency; +#if 0 // implement later struct { uint32_t threshold_bytes; // minimum number of bytes received to be considered as filled/ready }fifo_count; +#endif }; }audio_feedback_params_t; -- cgit v1.3.1 From e384d16d576089daa3a5c993ead06cffb7a50cbe Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 31 May 2022 21:52:54 +0700 Subject: clean up tud_audio_set_itf_cb() invocation --- src/class/audio/audio_device.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 01a42f34f..a2801e299 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1629,8 +1629,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif #endif - // Invoke callback - can be used to trigger data sampling if not already running - // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); // Schedule first transmit if alternate interface is not zero i.e. streaming is disabled - in case no sample data is available a ZLP is loaded // It is necessary to trigger this here since the refill is done with an RX FIFO empty interrupt which can only trigger if something was in there @@ -1662,16 +1660,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif #endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - // In case of asynchronous EP, call Cb after ep_fb is set - // if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) ) - // { - // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); - // } -#else - // Invoke callback - if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); -#endif // Prepare for incoming data #if USE_LINEAR_BUFFER_RX TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false); @@ -1688,12 +1676,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Enable SOF interrupt if callback is implemented if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true); - - // // Invoke callback after ep_out is set - // if (audio->ep_out != 0) - // { - // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); - // } } #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1705,10 +1687,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * TU_VERIFY(foundEPs == nEps); -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Invoke one callback for a final set interface if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Prepare feedback computation if callback is available if (tud_audio_feedback_params_cb) { -- cgit v1.3.1 From 8b9cf152a0dedda573fb3374d8c873dce4b883d1 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Jun 2022 16:51:17 +0700 Subject: rhport argument in usbd_ API() is not used (always use the initialized port) remove the usage of TUD_OPT_RHPORT in class driver --- examples/device/cdc_msc/src/tusb_config.h | 31 ++++++--------------- hw/bsp/lpc18/family.c | 35 +++++++++++++++-------- src/class/bth/bth_device.c | 6 ++-- src/class/cdc/cdc_device.c | 4 +-- src/class/hid/hid_device.c | 7 +++-- src/class/midi/midi_device.c | 4 +-- src/class/net/ecm_rndis_device.c | 10 ++++--- src/class/net/ncm_device.c | 9 +++--- src/class/vendor/vendor_device.c | 12 +++++--- src/common/tusb_mcu.h | 29 +++++++++---------- src/device/usbd.c | 14 +++++++++- src/device/usbd_pvt.h | 1 + src/tusb_option.h | 46 ++++++++++++++++--------------- 13 files changed, 114 insertions(+), 94 deletions(-) (limited to 'src/class') diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index 3849ad4d0..363da88d7 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -41,7 +41,12 @@ // This example doesn't use an RTOS #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE + #define CFG_TUSB_OS OPT_OS_NONE +#endif + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +#ifndef CFG_TUSB_DEBUG + #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack @@ -53,34 +58,14 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" -#endif - +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED -// Device max speed, default is max speed that hardware controller could support without external PHY -// BOARD_TUD_MAX_SPEED can be used to change value (e.g for board features external PHY). -#ifdef BOARD_TUD_MAX_SPEED - #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED -#else - #define CFG_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - - -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 - /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. diff --git a/hw/bsp/lpc18/family.c b/hw/bsp/lpc18/family.c index d74ebcd33..a59b6e89d 100644 --- a/hw/bsp/lpc18/family.c +++ b/hw/bsp/lpc18/family.c @@ -28,28 +28,40 @@ #include "bsp/board.h" #include "board.h" +#ifdef BOARD_TUD_RHPORT + #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) +#else + #define PORT_SUPPORT_DEVICE(_n) 0 +#endif + +#ifdef BOARD_TUH_RHPORT + #define PORT_SUPPORT_HOST(_n) (BOARD_TUH_RHPORT == _n) +#else + #define PORT_SUPPORT_HOST(_n) 0 +#endif + //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - tuh_int_handler(0); + #if PORT_SUPPORT_DEVICE(0) + tud_int_handler(0); #endif - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE - tud_int_handler(0); + #if PORT_SUPPORT_HOST(0) + tuh_int_handler(0); #endif } void USB1_IRQHandler(void) { - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST - tuh_int_handler(1); + #if PORT_SUPPORT_DEVICE(1) + tud_int_handler(1); #endif - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE - tud_int_handler(1); + #if PORT_SUPPORT_HOST(1) + tuh_int_handler(1); #endif } @@ -84,7 +96,8 @@ void board_init(void) SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - //NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif Chip_GPIO_Init(LPC_GPIO_PORT); @@ -102,11 +115,11 @@ void board_init(void) Chip_UART_TXEnable(UART_DEV); //------------- USB -------------// -#if CFG_TUSB_RHPORT0_MODE +#if PORT_SUPPORT_DEVICE(0) || PORT_SUPPORT_HOST(0) Chip_USB0_Init(); #endif -#if CFG_TUSB_RHPORT1_MODE +#if PORT_SUPPORT_DEVICE(1) || PORT_SUPPORT_HOST(1) Chip_USB1_Init(); #endif } diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index f40bfbd0d..f96bb3552 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -59,10 +59,12 @@ CFG_TUSB_MEM_SECTION btd_interface_t _btd_itf; static bool bt_tx_data(uint8_t ep, void *data, uint16_t len) { + uint8_t const rhport = 0; + // skip if previous transfer not complete - TU_VERIFY(!usbd_edpt_busy(TUD_OPT_RHPORT, ep)); + TU_VERIFY(!usbd_edpt_busy(rhport, ep)); - TU_ASSERT(usbd_edpt_xfer(TUD_OPT_RHPORT, ep, data, len)); + TU_ASSERT(usbd_edpt_xfer(rhport, ep, data, len)); return true; } diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 2b9b84e7a..7aa7a4860 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -82,7 +82,7 @@ CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { - uint8_t const rhport = TUD_OPT_RHPORT; + uint8_t const rhport = 0; uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); // Prepare for incoming data but only allow what we can store in the ring buffer. @@ -189,7 +189,7 @@ uint32_t tud_cdc_n_write_flush (uint8_t itf) // No data to send if ( !tu_fifo_count(&p_cdc->tx_ff) ) return 0; - uint8_t const rhport = TUD_OPT_RHPORT; + uint8_t const rhport = 0; // Claim the endpoint TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 ); diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 562ca7f36..cdf155e1c 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -76,8 +76,9 @@ static inline uint8_t get_index_by_itfnum(uint8_t itf_num) //--------------------------------------------------------------------+ bool tud_hid_n_ready(uint8_t instance) { + uint8_t const rhport = 0; uint8_t const ep_in = _hidd_itf[instance].ep_in; - return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(TUD_OPT_RHPORT, ep_in); + return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in); } bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint8_t len) @@ -103,7 +104,7 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, u memcpy(p_hid->epin_buf, report, len); } - return usbd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->epin_buf, len); + return usbd_edpt_xfer(rhport, p_hid->ep_in, p_hid->epin_buf, len); } uint8_t tud_hid_n_interface_protocol(uint8_t instance) @@ -172,7 +173,7 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, //--------------------------------------------------------------------+ void hidd_init(void) { - hidd_reset(TUD_OPT_RHPORT); + hidd_reset(0); } void hidd_reset(uint8_t rhport) diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 2ce1376bd..28e6a92d2 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -92,7 +92,7 @@ bool tud_midi_n_mounted (uint8_t itf) static void _prep_out_transaction (midid_interface_t* p_midi) { - uint8_t const rhport = TUD_OPT_RHPORT; + uint8_t const rhport = 0; uint16_t available = tu_fifo_remaining(&p_midi->rx_ff); // Prepare for incoming data but only allow what we can store in the ring buffer. @@ -219,7 +219,7 @@ static uint32_t write_flush(midid_interface_t* midi) // No data to send if ( !tu_fifo_count(&midi->tx_ff) ) return 0; - uint8_t const rhport = TUD_OPT_RHPORT; + uint8_t const rhport = 0; // skip if previous transfer not complete TU_VERIFY( usbd_edpt_claim(rhport, midi->ep_in), 0 ); diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c index f6b318058..d85a3f778 100644 --- a/src/class/net/ecm_rndis_device.c +++ b/src/class/net/ecm_rndis_device.c @@ -108,20 +108,22 @@ static bool can_xmit; void tud_network_recv_renew(void) { - usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_out, received, sizeof(received)); + usbd_edpt_xfer(0, _netd_itf.ep_out, received, sizeof(received)); } static void do_in_xfer(uint8_t *buf, uint16_t len) { can_xmit = false; - usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_in, buf, len); + usbd_edpt_xfer(0, _netd_itf.ep_in, buf, len); } void netd_report(uint8_t *buf, uint16_t len) { + uint8_t const rhport = 0; + // skip if previous report not yet acknowledged by host - if ( usbd_edpt_busy(TUD_OPT_RHPORT, _netd_itf.ep_notif) ) return; - usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_notif, buf, len); + if ( usbd_edpt_busy(rhport, _netd_itf.ep_notif) ) return; + usbd_edpt_xfer(rhport, _netd_itf.ep_notif, buf, len); } //--------------------------------------------------------------------+ diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 1987337f8..00892b49c 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -188,7 +188,7 @@ static void ncm_start_tx(void) { ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = 0; // Kick off an endpoint transfer - usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_in, ntb->data, ntb_length); + usbd_edpt_xfer(0, ncm_interface.ep_in, ntb->data, ntb_length); ncm_interface.transferring = true; // Swap to the other NTB and clear it out @@ -229,7 +229,7 @@ void tud_network_recv_renew(void) { if (!ncm_interface.num_datagrams) { - usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); + usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); return; } @@ -316,14 +316,15 @@ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 static void ncm_report(void) { + uint8_t const rhport = 0; if (ncm_interface.report_state == REPORT_SPEED) { ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); ncm_interface.report_state = REPORT_CONNECTED; ncm_interface.report_pending = true; } else if (ncm_interface.report_state == REPORT_CONNECTED) { ncm_notify_connected.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_connected, sizeof(ncm_notify_connected)); + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_connected, sizeof(ncm_notify_connected)); ncm_interface.report_state = REPORT_DONE; ncm_interface.report_pending = true; } diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 6e3ceb1c4..c7dfa0062 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -84,14 +84,16 @@ bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) //--------------------------------------------------------------------+ static void _prep_out_transaction (vendord_interface_t* p_itf) { + uint8_t const rhport = 0; + // skip if previous transfer not complete - if ( usbd_edpt_busy(TUD_OPT_RHPORT, p_itf->ep_out) ) return; + if ( usbd_edpt_busy(rhport, p_itf->ep_out) ) return; // Prepare for incoming data but only allow what we can store in the ring buffer. uint16_t max_read = tu_fifo_remaining(&p_itf->rx_ff); if ( max_read >= CFG_TUD_VENDOR_EPSIZE ) { - usbd_edpt_xfer(TUD_OPT_RHPORT, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); + usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); } } @@ -115,13 +117,15 @@ void tud_vendor_n_read_flush (uint8_t itf) //--------------------------------------------------------------------+ static uint16_t maybe_transmit(vendord_interface_t* p_itf) { + uint8_t const rhport = 0; + // skip if previous transfer not complete - TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, p_itf->ep_in) ); + TU_VERIFY( !usbd_edpt_busy(rhport, p_itf->ep_in) ); uint16_t count = tu_fifo_read_n(&p_itf->tx_ff, p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE); if (count > 0) { - TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, p_itf->ep_in, p_itf->epin_buf, count) ); + TU_ASSERT( usbd_edpt_xfer(rhport, p_itf->ep_in, p_itf->epin_buf, count) ); } return count; } diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c1cf2a810..383a8d686 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -45,8 +45,7 @@ * - ENDPOINT_MAX: max (logical) number of endpoint * - ENDPOINT_EXCLUSIVE_NUMBER: endpoint number with different direction IN and OUT aren't allowed, * e.g EP1 OUT & EP1 IN cannot exist together - * - RHPORT_HIGHSPEED: mask to indicate which port support highspeed mode (without external PHY) - * bit0 for port0 and so on. + * - RHPORT_HIGHSPEED: support highspeed with on-chip PHY */ //------------- NXP -------------// @@ -63,8 +62,7 @@ #define TUP_USBIP_EHCI #define TUP_DCD_ENDPOINT_MAX 6 - #define TUP_RHPORT_HIGHSPEED 0x01 // Port0 HS, Port1 FS - + #define TUP_RHPORT_HIGHSPEED 1 // Port0 HS, Port1 FS #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) #define TUP_DCD_ENDPOINT_MAX 5 @@ -82,8 +80,7 @@ #define TUP_USBIP_EHCI #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 0x03 // Port0 HS, Port1 HS - + #define TUP_RHPORT_HIGHSPEED 1 // Port0 HS, Port1 HS #elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX, OPT_MCU_K32L2BXX) #define TUP_DCD_ENDPOINT_MAX 16 @@ -107,7 +104,7 @@ #elif TU_CHECK_MCU(OPT_MCU_SAMX7X) #define TUP_DCD_ENDPOINT_MAX 10 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) @@ -155,7 +152,7 @@ // MCU with on-chip HS Phy #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) - #define TUP_RHPORT_HIGHSPEED 0x02 // Port 0: FS, Port 1: HS + #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS #endif #elif TU_CHECK_MCU(OPT_MCU_STM32H7) @@ -185,12 +182,12 @@ #endif #elif TU_CHECK_MCU(OPT_MCU_STM32WB) -#define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 //------------- Sony -------------// #elif TU_CHECK_MCU(OPT_MCU_CXD56) #define TUP_DCD_ENDPOINT_MAX 7 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER //------------- TI -------------// @@ -213,7 +210,7 @@ #elif TU_CHECK_MCU(OPT_MCU_NUC505) #define TUP_DCD_ENDPOINT_MAX 12 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 //------------- Espressif -------------// #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) @@ -228,7 +225,7 @@ #elif TU_CHECK_MCU(OPT_MCU_RP2040) #define TUP_DCD_ENDPOINT_MAX 16 - #define TU_ATTR_FAST_FUNC __attribute__((section(".time_critical.tinyusb"))) + #define TU_ATTR_FAST_FUNC __attribute__((section(".time_critical.tinyusb"))) //------------- Silabs -------------// #elif TU_CHECK_MCU(OPT_MCU_EFM32GG) @@ -248,7 +245,7 @@ #elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) #define TUP_USBIP_DWC2 #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 //------------- Broadcom -------------// #elif TU_CHECK_MCU(OPT_MCU_XMC4000) @@ -258,11 +255,11 @@ //------------- BridgeTek -------------// #elif TU_CHECK_MCU(OPT_MCU_FT90X) #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 #elif TU_CHECK_MCU(OPT_MCU_FT93X) #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 //------------ Allwinner -------------// #elif TU_CHECK_MCU(OPT_MCU_F1C100S) @@ -281,7 +278,7 @@ // Default to fullspeed if not defined #ifndef TUP_RHPORT_HIGHSPEED - #define TUP_RHPORT_HIGHSPEED 0x00 + #define TUP_RHPORT_HIGHSPEED 0 #endif // fast function, normally mean placing function in SRAM diff --git a/src/device/usbd.c b/src/device/usbd.c index fa75c0214..55e478a4e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -428,7 +428,6 @@ bool tud_init (uint8_t rhport) dcd_init(rhport); dcd_int_enable(rhport); - return true; } @@ -1199,6 +1198,8 @@ void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { + rhport = _usbd_rhport; + TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < CFG_TUD_ENDPPOINT_MAX); TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed)); @@ -1240,6 +1241,8 @@ bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { + rhport = _usbd_rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -1275,6 +1278,8 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // into the USB buffer! bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) { + rhport = _usbd_rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -1314,6 +1319,7 @@ bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -1330,6 +1336,8 @@ void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + rhport = _usbd_rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -1361,6 +1369,8 @@ bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) */ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + rhport = _usbd_rhport; + TU_ASSERT(dcd_edpt_close, /**/); TU_LOG2(" CLOSING Endpoint: 0x%02X\r\n", ep_addr); @@ -1377,6 +1387,8 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) void usbd_sof_enable(uint8_t rhport, bool en) { + rhport = _usbd_rhport; + // TODO: Check needed if all drivers including the user sof_cb does not need an active SOF ISR any more. // Only if all drivers switched off SOF calls the SOF interrupt may be disabled dcd_sof_enable(rhport, en); diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 603ffc936..17ebbfcd4 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -62,6 +62,7 @@ void usbd_int_set(bool enabled); //--------------------------------------------------------------------+ // USBD Endpoint API +// Note: rhport should be 0 since device stack only support 1 rhport for now //--------------------------------------------------------------------+ // Open an endpoint diff --git a/src/tusb_option.h b/src/tusb_option.h index ce22a8a6a..c198e4ef3 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -195,25 +195,21 @@ typedef int make_iso_compilers_happy ; #define OPT_MODE_HIGH_SPEED 0x0400 ///< High Speed #define OPT_MODE_SPEED_MASK 0xff00 -#ifndef CFG_TUSB_RHPORT0_MODE - #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE -#endif +//------------- Roothub as Device -------------// -#ifndef CFG_TUSB_RHPORT1_MODE - #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE -#endif +//#ifndef CFG_TUSB_RHPORT0_MODE +// #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE +//#endif +// +//#ifndef CFG_TUSB_RHPORT1_MODE +// #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE +//#endif -#if (((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST ) && ((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST )) || \ - (((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE) && ((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE)) - #error "TinyUSB currently does not support same modes on more than 1 roothub port" -#endif -//------------- Roothub as Device -------------// - -#if (CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE +#if defined(CFG_TUSB_RHPORT0_MODE) && ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE) #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) #define TUD_OPT_RHPORT 0 -#elif (CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE +#elif defined(CFG_TUSB_RHPORT1_MODE) && ((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE) #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT1_MODE) #define TUD_OPT_RHPORT 1 #else @@ -222,21 +218,24 @@ typedef int make_iso_compilers_happy ; #endif #ifndef CFG_TUD_ENABLED -#define CFG_TUD_ENABLED (TUD_RHPORT_MODE & OPT_MODE_DEVICE) + // fallback to use CFG_TUSB_RHPORTx_MODE + #define CFG_TUD_ENABLED (TUD_RHPORT_MODE & OPT_MODE_DEVICE) #endif -#if CFG_TUD_ENABLED - #define TUD_OPT_HIGH_SPEED ((TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) ? (TUD_RHPORT_MODE & OPT_MODE_HIGH_SPEED) : (TUP_RHPORT_HIGHSPEED & (1 << TUD_OPT_RHPORT))) -#else - #define TUD_OPT_HIGH_SPEED 0 +#ifndef CFG_TUD_MAX_SPEED + // fallback to use CFG_TUSB_RHPORTx_MODE + #define CFG_TUD_MAX_SPEED (TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) #endif +// highspeed support indicator +#define TUD_OPT_HIGH_SPEED (CFG_TUD_MAX_SPEED ? CFG_TUD_MAX_SPEED : TUP_RHPORT_HIGHSPEED) + //------------- Roothub as Host -------------// -#if (CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST +#if defined(CFG_TUSB_RHPORT0_MODE) && ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST) #define TUH_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) #define TUH_OPT_RHPORT 0 -#elif (CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST +#elif defined(CFG_TUSB_RHPORT1_MODE) && ((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST) #define TUH_RHPORT_MODE (CFG_TUSB_RHPORT1_MODE) #define TUH_OPT_RHPORT 1 #else @@ -244,7 +243,10 @@ typedef int make_iso_compilers_happy ; #define TUH_OPT_RHPORT -1 #endif -#define CFG_TUH_ENABLED (TUH_RHPORT_MODE & OPT_MODE_HOST) +#ifndef CFG_TUH_ENABLED + // fallback to use CFG_TUSB_RHPORTx_MODE + #define CFG_TUH_ENABLED (TUH_RHPORT_MODE & OPT_MODE_HOST) +#endif // For backward compatible #define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED -- cgit v1.3.1 From 06392247ebce685a7bd81da4f3f38722767288c2 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 7 Jun 2022 11:50:50 +0700 Subject: add TU_ATTR_FAST_FUNC for audio sof isr call chain --- src/class/audio/audio_device.c | 2 +- src/class/audio/audio_device.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a2801e299..dbd8ab54b 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2114,7 +2114,7 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) } #endif -void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) +TU_ATTR_FAST_FUNC void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) { (void) rhport; (void) frame_count; diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 13f24fb62..0ef100fa4 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -524,10 +524,10 @@ typedef struct { TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); // Callback in ISR context, invoked periodically according to feedback endpoint bInterval. -// Could be used to compute and update feedback value +// Could be used to compute and update feedback value, should be placed in RAM if possible // frame_number : current SOF count // interval_shift: number of bit shift i.e log2(interval) from Feedback endpoint descriptor -TU_ATTR_WEAK void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift); +TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift); #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -- cgit v1.3.1 From e9089b993f32a5437614008ec14458ad577cc28f Mon Sep 17 00:00:00 2001 From: Maddy Date: Thu, 16 Jun 2022 16:22:55 -0700 Subject: Fix typo in audiod_rx_done_cb in audio_device.c --- src/class/audio/audio_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index dbd8ab54b..1e534b6a4 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -562,7 +562,7 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t case AUDIO_FORMAT_TYPE_I: - switch (audio->format_type_I_tx) + switch (audio->format_type_I_rx) { case AUDIO_DATA_FORMAT_TYPE_I_PCM: TU_VERIFY(audiod_decode_type_I_pcm(rhport, audio, n_bytes_received)); -- cgit v1.3.1 From 905a0b24576deab6a2b4214b1428c87e4cd703a5 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 17 Jun 2022 14:37:35 +0700 Subject: correct bulk size for highspeed endpoint in dynamic_configuration and usbtmc exmaples --- examples/device/dynamic_configuration/src/usb_descriptors.c | 2 +- src/class/usbtmc/usbtmc_device.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index 3352972a5..b88f20163 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -163,7 +163,7 @@ uint8_t const desc_configuration_0[] = TUD_CONFIG_DESCRIPTOR(1, ITF_0_NUM_TOTAL, 0, CONFIG_0_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. - TUD_CDC_DESCRIPTOR(ITF_0_NUM_CDC, 0, EPNUM_0_CDC_NOTIF, 8, EPNUM_0_CDC_OUT, EPNUM_0_CDC_IN, 64), + TUD_CDC_DESCRIPTOR(ITF_0_NUM_CDC, 0, EPNUM_0_CDC_NOTIF, 8, EPNUM_0_CDC_OUT, EPNUM_0_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), // Interface number, string index, EP Out & EP In address, EP size TUD_MIDI_DESCRIPTOR(ITF_0_NUM_MIDI, 0, EPNUM_0_MIDI_OUT, EPNUM_0_MIDI_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 0549a1569..5dc4d2dff 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -37,7 +37,7 @@ // USB spec says that full-speed must be 8,16,32, or 64. // However, this driver implementation requires it to be >=32 -#define USBTMCD_MAX_PACKET_SIZE (64u) +#define USBTMCD_MAX_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) /*********************************************** * Functions to be implemeted by the class implementation -- cgit v1.3.1 From e9c29e6a2d42f931ededbc3ad1467cdd5dc1ea33 Mon Sep 17 00:00:00 2001 From: NConrad Date: Tue, 21 Jun 2022 21:27:52 -0400 Subject: Update USBTMC driver to support dynamic packet sizes (based on descriptor). --- src/class/usbtmc/usbtmc_device.c | 36 ++++++++++++++++++++++-------------- src/class/usbtmc/usbtmc_device.h | 4 ---- 2 files changed, 22 insertions(+), 18 deletions(-) (limited to 'src/class') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index b02b07575..9608e4835 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -64,7 +64,8 @@ // USBTMC 3.2.2 error conditions not strictly followed // No local lock-out, REN, or GTL. // Clear message available status byte at the correct time? (488 4.3.1.3) - +// Ability to defer status byte transmission +// Transmission of status byte in response to USB488 SRQ condition #include "tusb_option.h" @@ -80,6 +81,11 @@ static char logMsg[150]; #endif +// Buffer size must be an exact multiple of the max packet size for both +// bulk (up to 64 bytes for FS, 512 bytes for HS). In addation, this driver +// imposes a minimum buffer size of 32 bytes. +#define USBTMCD_BUFFER_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + /* * The state machine does not allow simultaneous reading and writing. This is * consistent with USBTMC. @@ -120,9 +126,12 @@ typedef struct uint8_t ep_int_in; // IN buffer is only used for first packet, not the remainder // in order to deal with prepending header - CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_in_buf[USBTMCD_MAX_PACKET_SIZE]; + CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_in_buf[USBTMCD_BUFFER_SIZE]; + uint32_t ep_bulk_in_wMaxPacketSize; // OUT buffer receives one packet at a time - CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_out_buf[USBTMCD_MAX_PACKET_SIZE]; + CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_out_buf[USBTMCD_BUFFER_SIZE]; + uint32_t ep_bulk_out_wMaxPacketSize; + uint32_t transfer_size_remaining; // also used for requested length for bulk IN. uint32_t transfer_size_sent; // To keep track of data bytes that have been queued in FIFO (not header bytes) @@ -139,11 +148,8 @@ CFG_TUSB_MEM_SECTION static usbtmc_interface_state_t usbtmc_state = .itf_id = 0xFF, }; -// We need all headers to fit in a single packet in this implementation. -TU_VERIFY_STATIC(USBTMCD_MAX_PACKET_SIZE >= 32u,"USBTMC dev EP packet size too small"); -TU_VERIFY_STATIC( - (sizeof(usbtmc_state.ep_bulk_in_buf) % USBTMCD_MAX_PACKET_SIZE) == 0, - "packet buffer must be a multiple of the packet size"); +// We need all headers to fit in a single packet in this implementation, 32 bytes will fit all standard USBTMC headers +TU_VERIFY_STATIC(USBTMCD_BUFFER_SIZE >= 32u,"USBTMC dev buffer size too small"); static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len); static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen); @@ -151,7 +157,6 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack static uint8_t termChar; static uint8_t termCharRequested = false; - osal_mutex_def_t usbtmcLockBuffer; static osal_mutex_t usbtmcLock; @@ -282,12 +287,15 @@ uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *)p_desc; switch(ep_desc->bmAttributes.xfer) { case TUSB_XFER_BULK: - TU_ASSERT(tu_edpt_packet_size(ep_desc) == USBTMCD_MAX_PACKET_SIZE, 0); + // Ensure buffer is an exact multiple of the maxPacketSize + TU_ASSERT((USBTMCD_BUFFER_SIZE % tu_edpt_packet_size(ep_desc)) == 0, 0); if (tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN) { usbtmc_state.ep_bulk_in = ep_desc->bEndpointAddress; + usbtmc_state.ep_bulk_in_wMaxPacketSize = tu_edpt_packet_size(ep_desc); } else { usbtmc_state.ep_bulk_out = ep_desc->bEndpointAddress; + usbtmc_state.ep_bulk_out_wMaxPacketSize = tu_edpt_packet_size(ep_desc); } break; @@ -395,7 +403,7 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack // return true upon failure, as we can assume error is being handled elsewhere. TU_VERIFY(usbtmc_state.state == STATE_RCV,true); - bool shortPacket = (packetLen < USBTMCD_MAX_PACKET_SIZE); + bool shortPacket = (packetLen < usbtmc_state.ep_bulk_out_wMaxPacketSize); // Packet is to be considered complete when we get enough data or at a short packet. bool atEnd = false; @@ -522,7 +530,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint break; case STATE_TX_INITIATED: - if(usbtmc_state.transfer_size_remaining >=sizeof(usbtmc_state.ep_bulk_in_buf)) + if(usbtmc_state.transfer_size_remaining >= sizeof(usbtmc_state.ep_bulk_in_buf)) { // FIXME! This removes const below! TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, @@ -539,7 +547,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint usbtmc_state.transfer_size_remaining = 0; usbtmc_state.devInBuffer = NULL; TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf, (uint16_t)packetLen) ); - if(((packetLen % USBTMCD_MAX_PACKET_SIZE) != 0) || (packetLen == 0 )) + if(((packetLen % usbtmc_state.ep_bulk_in_wMaxPacketSize) != 0) || (packetLen == 0 )) { usbtmc_state.state = STATE_TX_SHORTED; } @@ -680,7 +688,7 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request usbtmc_state.transfer_size_remaining = 0u; // Check if we've queued a short packet criticalEnter(); - usbtmc_state.state = ((usbtmc_state.transfer_size_sent % USBTMCD_MAX_PACKET_SIZE) == 0) ? + usbtmc_state.state = ((usbtmc_state.transfer_size_sent % usbtmc_state.ep_bulk_in_wMaxPacketSize) == 0) ? STATE_ABORTING_BULK_IN : STATE_ABORTING_BULK_IN_SHORTED; criticalLeave(); if(usbtmc_state.transfer_size_sent == 0) diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 5dc4d2dff..144b3315d 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -35,10 +35,6 @@ #define CFG_TUD_USBTMC_ENABLE_488 (1) #endif -// USB spec says that full-speed must be 8,16,32, or 64. -// However, this driver implementation requires it to be >=32 -#define USBTMCD_MAX_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) - /*********************************************** * Functions to be implemeted by the class implementation */ -- cgit v1.3.1 From 4f6e770eda9f8c605b238f35def1edaff93a8fb8 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 Jun 2022 19:45:49 +0700 Subject: add more warning option, also fix -Wconversion with rp2040 -Wuninitialized, -Wunused, -Wredundant-decls --- examples/device/cdc_msc/src/usb_descriptors.c | 2 +- examples/make.mk | 7 ++++- hw/bsp/broadcom_32bit/family.mk | 2 +- hw/bsp/broadcom_64bit/family.mk | 2 +- hw/bsp/imxrt/family.mk | 2 +- hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c | 1 - hw/bsp/nrf/family.mk | 3 ++ hw/bsp/rx/family.mk | 3 ++ hw/bsp/samd21/family.mk | 2 +- hw/bsp/saml2x/family.mk | 2 +- hw/mcu/raspberry_pi/Pico-PIO-USB | 2 +- src/class/cdc/cdc_device.c | 6 ++-- src/class/msc/msc_device.c | 33 +++++++++++----------- src/common/tusb_fifo.c | 12 ++++---- src/device/usbd.c | 16 +++++++---- src/device/usbd_control.c | 2 +- src/portable/synopsys/dwc2/dwc2_stm32.h | 3 +- 17 files changed, 58 insertions(+), 42 deletions(-) (limited to 'src/class') diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index 09894cf1b..6b59ed50f 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -282,7 +282,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/make.mk b/examples/make.mk index bed46d02b..26065c027 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -108,8 +108,13 @@ CFLAGS += \ -Wcast-align \ -Wcast-function-type \ -Wcast-qual \ - -Wnull-dereference + -Wnull-dereference \ + -Wuninitialized \ + -Wunused \ + -Wredundant-decls +# -Wconversion \ + # Debugging/Optimization ifeq ($(DEBUG), 1) CFLAGS += -Og diff --git a/hw/bsp/broadcom_32bit/family.mk b/hw/bsp/broadcom_32bit/family.mk index 98744c5d0..cf68e21ee 100644 --- a/hw/bsp/broadcom_32bit/family.mk +++ b/hw/bsp/broadcom_32bit/family.mk @@ -16,7 +16,7 @@ CFLAGS += \ CROSS_COMPILE = arm-none-eabi- # mcu driver cause following warnings -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ diff --git a/hw/bsp/broadcom_64bit/family.mk b/hw/bsp/broadcom_64bit/family.mk index 723926734..97af6d64a 100644 --- a/hw/bsp/broadcom_64bit/family.mk +++ b/hw/bsp/broadcom_64bit/family.mk @@ -15,7 +15,7 @@ CFLAGS += \ CROSS_COMPILE = aarch64-none-elf- # mcu driver cause following warnings -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ diff --git a/hw/bsp/imxrt/family.mk b/hw/bsp/imxrt/family.mk index c81e67eb6..0a55b740b 100644 --- a/hw/bsp/imxrt/family.mk +++ b/hw/bsp/imxrt/family.mk @@ -23,7 +23,7 @@ CFLAGS += -DBOARD_TUH_RHPORT=$(BOARD_TUH_RHPORT) endif # mcu driver cause following warnings -CFLAGS += -Wno-error=unused-parameter -Wno-error=implicit-fallthrough= +CFLAGS += -Wno-error=unused-parameter -Wno-error=implicit-fallthrough -Wno-error=redundant-decls MCU_DIR = $(SDK_DIR)/devices/$(MCU_VARIANT) diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c b/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c index cff7bc15e..9793ba241 100644 --- a/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c +++ b/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c @@ -52,7 +52,6 @@ void USB_DeviceClockInit (void) //--------------------------------------------------------------------+ // LED -void board_led_write (bool state); extern u32 SystemCoreClock; const int baudrate = 115200; diff --git a/hw/bsp/nrf/family.mk b/hw/bsp/nrf/family.mk index d8283a9e6..609e2da0b 100644 --- a/hw/bsp/nrf/family.mk +++ b/hw/bsp/nrf/family.mk @@ -16,6 +16,9 @@ CFLAGS += \ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=undef -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=cast-qual +# warning caused by dcd_nrf5x.c due to include of usbd.h and re-declare of dcd_int_handler() +CFLAGS += -Wno-error=redundant-decls + # All source paths should be relative to the top level. LD_FILE ?= hw/bsp/nrf/boards/$(BOARD)/nrf52840_s140_v6.ld diff --git a/hw/bsp/rx/family.mk b/hw/bsp/rx/family.mk index aba05812d..f4f8ae088 100644 --- a/hw/bsp/rx/family.mk +++ b/hw/bsp/rx/family.mk @@ -13,6 +13,9 @@ CFLAGS += \ -mlittle-endian-data \ -DSSIZE_MAX=__INT_MAX__ +# suppress warning caused by vendor mcu driver +CFLAGS += -Wno-error=redundant-decls + SRC_C += \ src/portable/renesas/usba/dcd_usba.c \ src/portable/renesas/usba/hcd_usba.c \ diff --git a/hw/bsp/samd21/family.mk b/hw/bsp/samd21/family.mk index 208f23789..95421e753 100644 --- a/hw/bsp/samd21/family.mk +++ b/hw/bsp/samd21/family.mk @@ -13,7 +13,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_SAMD21 # suppress warning caused by vendor mcu driver -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ diff --git a/hw/bsp/saml2x/family.mk b/hw/bsp/saml2x/family.mk index bb1faeb7f..afb0afc03 100644 --- a/hw/bsp/saml2x/family.mk +++ b/hw/bsp/saml2x/family.mk @@ -14,7 +14,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_SAML22 # suppress warning caused by vendor mcu driver -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ diff --git a/hw/mcu/raspberry_pi/Pico-PIO-USB b/hw/mcu/raspberry_pi/Pico-PIO-USB index 2a9fefd6c..92bd3b4c3 160000 --- a/hw/mcu/raspberry_pi/Pico-PIO-USB +++ b/hw/mcu/raspberry_pi/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 2a9fefd6ccf42e5d8570ae83fdc54c9c875ebdd1 +Subproject commit 92bd3b4c3ad2fce36166e4a357749b6d4fe9013b diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 7aa7a4860..fab6f0035 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -145,7 +145,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, bufsize); + uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) bufsize); _prep_out_transaction(p_cdc); return num_read; } @@ -168,7 +168,7 @@ void tud_cdc_n_read_flush (uint8_t itf) uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, bufsize); + uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) bufsize); // flush if queue more than packet size if ( tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE ) @@ -435,7 +435,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Received new data if ( ep_addr == p_cdc->ep_out ) { - tu_fifo_write_n(&p_cdc->rx_ff, &p_cdc->epout_buf, xferred_bytes); + tu_fifo_write_n(&p_cdc->rx_ff, &p_cdc->epout_buf, (uint16_t) xferred_bytes); // Check for wanted char and invoke callback if needed if ( tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1) ) diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 3facb76d6..33dd4ac37 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -463,7 +463,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t { // Didn't check for case 9 (Ho > Dn), which requires examining scsi command first // but it is OK to just receive data then responded with failed status - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) ); + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, (uint16_t) p_msc->total_len) ); } }else { @@ -473,7 +473,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // Invoke user callback if not built-in if ( (resplen < 0) && (p_msc->sense_key == 0) ) { - resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len); + resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, (uint16_t) p_msc->total_len); } if ( resplen < 0 ) @@ -506,7 +506,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t { // cannot return more than host expect p_msc->total_len = tu_min32((uint32_t) resplen, p_cbw->total_bytes); - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) ); + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, (uint16_t) p_msc->total_len) ); } } } @@ -541,7 +541,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // OUT transfer, invoke callback if needed if ( !is_data_in(p_cbw->dir) ) { - int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len); + int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, (uint16_t) p_msc->total_len); if ( cb_result < 0 ) { @@ -707,7 +707,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ read_capa10.block_size = tu_htonl(block_size); resplen = sizeof(read_capa10); - memcpy(buffer, &read_capa10, resplen); + memcpy(buffer, &read_capa10, (size_t) resplen); } } break; @@ -741,7 +741,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ read_fmt_capa.block_size_u16 = tu_htons(block_size); resplen = sizeof(read_fmt_capa); - memcpy(buffer, &read_fmt_capa, resplen); + memcpy(buffer, &read_fmt_capa, (size_t) resplen); } } break; @@ -764,7 +764,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ tud_msc_inquiry_cb(lun, inquiry_rsp.vendor_id, inquiry_rsp.product_id, inquiry_rsp.product_rev); resplen = sizeof(inquiry_rsp); - memcpy(buffer, &inquiry_rsp, resplen); + memcpy(buffer, &inquiry_rsp, (size_t) resplen); } break; @@ -788,7 +788,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ mode_resp.write_protected = !writable; resplen = sizeof(mode_resp); - memcpy(buffer, &mode_resp, resplen); + memcpy(buffer, &mode_resp, (size_t) resplen); } break; @@ -801,17 +801,17 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ }; sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8; - sense_rsp.sense_key = p_msc->sense_key; + sense_rsp.sense_key = (uint8_t) (p_msc->sense_key & 0x0F); sense_rsp.add_sense_code = p_msc->add_sense_code; sense_rsp.add_sense_qualifier = p_msc->add_sense_qualifier; resplen = sizeof(sense_rsp); - memcpy(buffer, &sense_rsp, resplen); + memcpy(buffer, &sense_rsp, (size_t) resplen); // request sense callback could overwrite the sense data if (tud_msc_request_sense_cb) { - resplen = tud_msc_request_sense_cb(lun, buffer, bufsize); + resplen = tud_msc_request_sense_cb(lun, buffer, (uint16_t) bufsize); } // Clear sense data after copy @@ -859,7 +859,7 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) } else { - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, nbytes), ); + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, (uint16_t) nbytes), ); } } @@ -883,7 +883,7 @@ static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc) } // remaining bytes capped at class buffer - int32_t nbytes = (int32_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len); + uint16_t nbytes = (uint16_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len); // Write10 callback will be called later when usb transfer complete TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, nbytes), ); @@ -921,14 +921,15 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 // Application consume less than what we got (including zero) if ( (uint32_t) nbytes < xferred_bytes ) { + uint32_t const left_over = xferred_bytes - (uint32_t) nbytes; if ( nbytes > 0 ) { - p_msc->xferred_len += nbytes; - memmove(_mscd_buf, _mscd_buf+nbytes, xferred_bytes-nbytes); + p_msc->xferred_len += (uint16_t) nbytes; + memmove(_mscd_buf, _mscd_buf+nbytes, left_over); } // simulate an transfer complete with adjusted parameters --> callback will be invoked with adjusted parameter - dcd_event_xfer_complete(rhport, p_msc->ep_out, xferred_bytes-nbytes, XFER_RESULT_SUCCESS, false); + dcd_event_xfer_complete(rhport, p_msc->ep_out, left_over, XFER_RESULT_SUCCESS, false); } else { diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 183c9c6fc..895b9208b 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -79,7 +79,7 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si // Limit index space to 2*depth - this allows for a fast "modulo" calculation // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable // only if overflow happens once (important for unsupervised DMA applications) - f->max_pointer_idx = 2*depth - 1; + f->max_pointer_idx = (uint16_t) (2*depth - 1); f->non_used_index_space = UINT16_MAX - f->max_pointer_idx; f->rd_idx = f->wr_idx = 0; @@ -205,7 +205,7 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t uint8_t rem = nLin_bytes & 0x03; if (rem > 0) { - uint8_t remrem = tu_min16(nWrap_bytes, 4-rem); + uint8_t remrem = (uint8_t) tu_min16(nWrap_bytes, 4-rem); nWrap_bytes -= remrem; uint32_t tmp32 = *rx_fifo; @@ -288,7 +288,7 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu uint8_t rem = nLin_bytes & 0x03; if (rem > 0) { - uint8_t remrem = tu_min16(nWrap_bytes, 4-rem); + uint8_t remrem = (uint8_t) tu_min16(nWrap_bytes, 4-rem); nWrap_bytes -= remrem; uint32_t tmp32=0; @@ -325,7 +325,7 @@ static uint16_t advance_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) // We are exploiting the wrap around to the correct index if ((p > (uint16_t)(p + offset)) || ((uint16_t)(p + offset) > f->max_pointer_idx)) { - p = (p + offset) + f->non_used_index_space; + p = (uint16_t) ((p + offset) + f->non_used_index_space); } else { @@ -342,7 +342,7 @@ static uint16_t backward_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) // We are exploiting the wrap around to the correct index if ((p < (uint16_t)(p - offset)) || ((uint16_t)(p - offset) > f->max_pointer_idx)) { - p = (p - offset) - f->non_used_index_space; + p = (uint16_t) ((p - offset) - f->non_used_index_space); } else { @@ -818,7 +818,7 @@ bool tu_fifo_clear(tu_fifo_t *f) _ff_lock(f->mutex_rd); f->rd_idx = f->wr_idx = 0; - f->max_pointer_idx = 2*f->depth-1; + f->max_pointer_idx = (uint16_t) (2*f->depth-1); f->non_used_index_space = UINT16_MAX - f->max_pointer_idx; _ff_unlock(f->mutex_wr); diff --git a/src/device/usbd.c b/src/device/usbd.c index 1806281ff..fa894accc 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -409,6 +409,7 @@ bool tud_init (uint8_t rhport) for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const * driver = get_driver(i); + TU_ASSERT(driver); TU_LOG2("%s init\r\n", driver->name); driver->init(); } @@ -426,7 +427,9 @@ static void configuration_reset(uint8_t rhport) { for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) { - get_driver(i)->reset(rhport); + usbd_class_driver_t const * driver = get_driver(i); + TU_ASSERT(driver, ); + driver->reset(rhport); } tu_varclr(&_usbd_dev); @@ -735,7 +738,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Device status bit mask // - Bit 0: Self Powered // - Bit 1: Remote Wakeup enabled - uint16_t status = (_usbd_dev.self_powered ? 1 : 0) | (_usbd_dev.remote_wakeup_en ? 2 : 0); + uint16_t status = (uint16_t) ((_usbd_dev.self_powered ? 1u : 0u) | (_usbd_dev.remote_wakeup_en ? 2u : 0u)); tud_control_xfer(rhport, p_request, &status, 2); } break; @@ -867,8 +870,8 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) TU_ASSERT(desc_cfg != NULL && desc_cfg->bDescriptorType == TUSB_DESC_CONFIGURATION); // Parse configuration descriptor - _usbd_dev.remote_wakeup_support = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP) ? 1 : 0; - _usbd_dev.self_powered = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_SELF_POWERED ) ? 1 : 0; + _usbd_dev.remote_wakeup_support = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP) ? 1u : 0u; + _usbd_dev.self_powered = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_SELF_POWERED ) ? 1u : 0u; // Parse interface descriptor uint8_t const * p_desc = ((uint8_t const*) desc_cfg) + sizeof(tusb_desc_configuration_t); @@ -895,11 +898,12 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc; // Find driver for this interface - uint16_t const remaining_len = desc_end-p_desc; + uint16_t const remaining_len = (uint16_t) (desc_end-p_desc); uint8_t drv_id; for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { usbd_class_driver_t const *driver = get_driver(drv_id); + TU_ASSERT(driver); uint16_t const drv_len = driver->open(rhport, desc_itf, remaining_len); if ( (sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len) ) @@ -1101,7 +1105,7 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const * driver = get_driver(i); - if (driver->sof) + if (driver && driver->sof) { driver->sof(event->rhport, event->sof.frame_count); } diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 4f4108090..94a952df7 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -189,7 +189,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result TU_LOG_MEM(2, _usbd_ctrl_buf, xferred_bytes, 2); } - _ctrl_xfer.total_xferred += xferred_bytes; + _ctrl_xfer.total_xferred += (uint16_t) xferred_bytes; _ctrl_xfer.buffer += xferred_bytes; // Data Stage is complete when all request's length are transferred or diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index b500ddc46..1d849541e 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -103,7 +103,8 @@ static const dwc2_controller_t _dwc2_controller[] = // //--------------------------------------------------------------------+ -extern uint32_t SystemCoreClock; +// SystemCoreClock is alrady included by family header +// extern uint32_t SystemCoreClock; TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) -- cgit v1.3.1 From 0042eccb3b2ff0f980f3a927a271364a2089ada5 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 Jun 2022 22:22:52 +0700 Subject: fix redundant-decls warnings by usbd/usbh --- examples/make.mk | 6 +++--- hw/bsp/nrf/family.mk | 3 --- src/class/msc/msc_device.c | 2 +- src/device/dcd.h | 7 ------- src/device/usbd.c | 2 +- src/device/usbd.h | 5 ++++- src/device/usbd_control.c | 2 +- src/host/hub.c | 1 + src/host/usbh.c | 3 +-- src/host/usbh.h | 6 ++++-- 10 files changed, 16 insertions(+), 21 deletions(-) (limited to 'src/class') diff --git a/examples/make.mk b/examples/make.mk index 26065c027..fa909ddca 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -90,13 +90,13 @@ CFLAGS += \ -ffunction-sections \ -fsingle-precision-constant \ -fno-strict-aliasing \ - -Wdouble-promotion \ - -Wstrict-prototypes \ - -Wstrict-overflow \ -Wall \ -Wextra \ -Werror \ -Wfatal-errors \ + -Wdouble-promotion \ + -Wstrict-prototypes \ + -Wstrict-overflow \ -Werror-implicit-function-declaration \ -Wfloat-equal \ -Wundef \ diff --git a/hw/bsp/nrf/family.mk b/hw/bsp/nrf/family.mk index 609e2da0b..d8283a9e6 100644 --- a/hw/bsp/nrf/family.mk +++ b/hw/bsp/nrf/family.mk @@ -16,9 +16,6 @@ CFLAGS += \ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=undef -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=cast-qual -# warning caused by dcd_nrf5x.c due to include of usbd.h and re-declare of dcd_int_handler() -CFLAGS += -Wno-error=redundant-decls - # All source paths should be relative to the top level. LD_FILE ?= hw/bsp/nrf/boards/$(BOARD)/nrf52840_s140_v6.ld diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 33dd4ac37..00b0a1d06 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -28,9 +28,9 @@ #if (CFG_TUD_ENABLED && CFG_TUD_MSC) +#include "device/dcd.h" // for faking dcd_event_xfer_complete #include "device/usbd.h" #include "device/usbd_pvt.h" -#include "device/dcd.h" // for faking dcd_event_xfer_complete #include "msc_device.h" diff --git a/src/device/dcd.h b/src/device/dcd.h index 6b99734fe..c1780f656 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -110,14 +110,7 @@ typedef struct TU_ATTR_ALIGNED(4) void dcd_init (uint8_t rhport); // Interrupt Handler -#if __GNUC__ && !defined(__ARMCC_VERSION) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wredundant-decls" -#endif void dcd_int_handler(uint8_t rhport); -#if __GNUC__ && !defined(__ARMCC_VERSION) -#pragma GCC diagnostic pop -#endif // Enable device interrupt void dcd_int_enable (uint8_t rhport); diff --git a/src/device/usbd.c b/src/device/usbd.c index fa894accc..b2053174e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -28,12 +28,12 @@ #if CFG_TUD_ENABLED +#include "device/dcd.h" #include "tusb.h" #include "common/tusb_private.h" #include "device/usbd.h" #include "device/usbd_pvt.h" -#include "device/dcd.h" //--------------------------------------------------------------------+ // USBD Configuration diff --git a/src/device/usbd.h b/src/device/usbd.h index 964cfb992..17b4d927b 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -58,8 +58,11 @@ void tud_task (void) // Check if there is pending events need processing by tud_task() bool tud_task_event_ready(void); -// Interrupt handler, name alias to DCD +#ifndef _TUSB_DCD_H_ extern void dcd_int_handler(uint8_t rhport); +#endif + +// Interrupt handler, name alias to DCD #define tud_int_handler dcd_int_handler // Get current bus speed diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 94a952df7..0995ef669 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -28,9 +28,9 @@ #if CFG_TUD_ENABLED +#include "dcd.h" #include "tusb.h" #include "device/usbd_pvt.h" -#include "dcd.h" #if CFG_TUSB_DEBUG >= 2 extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); diff --git a/src/host/hub.c b/src/host/hub.c index 5c0fd9166..3400b154a 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -28,6 +28,7 @@ #if (CFG_TUH_ENABLED && CFG_TUH_HUB) +#include "hcd.h" #include "usbh.h" #include "usbh_classdriver.h" #include "hub.h" diff --git a/src/host/usbh.c b/src/host/usbh.c index 4807d20b8..4c9b0b1ba 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -28,10 +28,9 @@ #if CFG_TUH_ENABLED +#include "host/hcd.h" #include "tusb.h" #include "common/tusb_private.h" - -#include "host/usbh.h" #include "host/usbh_classdriver.h" #include "hub.h" diff --git a/src/host/usbh.h b/src/host/usbh.h index 347c75b8c..560a1ea23 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -32,7 +32,6 @@ #endif #include "common/tusb_common.h" -#include "hcd.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -115,8 +114,11 @@ void tuh_task(void) tuh_task_ext(UINT32_MAX, false); } -// Interrupt handler, name alias to HCD +#ifndef _TUSB_HCD_H_ extern void hcd_int_handler(uint8_t rhport); +#endif + +// Interrupt handler, name alias to HCD #define tuh_int_handler hcd_int_handler bool tuh_vid_pid_get(uint8_t daddr, uint16_t* vid, uint16_t* pid); -- cgit v1.3.1 From 239b5d52790051949c281e60ba96ac674669f026 Mon Sep 17 00:00:00 2001 From: NConrad Date: Fri, 24 Jun 2022 23:06:32 -0400 Subject: USBTMC: Manually stall and unstall EP when clear(ENDPOINT_HALT) is received. --- src/class/usbtmc/usbtmc_device.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 9608e4835..b5232ab91 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -597,18 +597,31 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request { uint32_t ep_addr = (request->wIndex); + // At this point, a transfer MAY be in progress. Based on USB spec, when clearing bulk EP HALT, + // the EP transfer buffer needs to be cleared and DTOG needs to be reset, even if + // the EP is not halted. The only USBD API interface to do this is to stall and then unstall the EP. if(ep_addr == usbtmc_state.ep_bulk_out) { criticalEnter(); + usbd_edpt_stall(rhport, ep_addr); + usbd_edpt_clear_stall(rhport, ep_addr); usbtmc_state.state = STATE_NAK; // USBD core has placed EP in NAK state for us criticalLeave(); tud_usbtmc_bulkOut_clearFeature_cb(); } else if (ep_addr == usbtmc_state.ep_bulk_in) { + usbd_edpt_stall(rhport, ep_addr); + usbd_edpt_clear_stall(rhport, ep_addr); tud_usbtmc_bulkIn_clearFeature_cb(); } - else + else if ((usbtmc_state.ep_int_in != 0) && (ep_addr == usbtmc_state.ep_int_in)) + { + // Clearing interrupt in EP + usbd_edpt_stall(rhport, ep_addr); + usbd_edpt_clear_stall(rhport, ep_addr); + } + else { return false; } @@ -836,6 +849,7 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request }, .StatusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)) }; + // USB488 spec states that transfer must be queued before control request response sent. usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg, sizeof(intMsg)); } else -- cgit v1.3.1 From c675debfb2dcff1697cb6643afb60c26309bdfcf Mon Sep 17 00:00:00 2001 From: NConrad Date: Sun, 26 Jun 2022 14:34:34 -0400 Subject: USBTMC: Handle busy interrupt in. --- src/class/usbtmc/usbtmc.h | 5 ++++- src/class/usbtmc/usbtmc_device.c | 32 +++++++++++++++++++------------- 2 files changed, 23 insertions(+), 14 deletions(-) (limited to 'src/class') diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index 7d7005c2e..e7016ae24 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -189,7 +189,10 @@ typedef enum { USBTMC_STATUS_FAILED = 0x80, USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS = 0x81, USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS = 0x82, - USBTMC_STATUS_SPLIT_IN_PROGRESS = 0x83 + USBTMC_STATUS_SPLIT_IN_PROGRESS = 0x83, + + /****** USBTMC 488 *************/ + USB488_STATUS_INTERRUPT_IN_BUSY = 0x20 } usbtmc_status_enum; /************************************************************ diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index b5232ab91..c50ca65d5 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -831,26 +831,32 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request bTag = request->wValue & 0x7F; TU_VERIFY(request->bmRequestType == 0xA1); - TU_VERIFY((request->wValue & (~0x7F)) == 0u); // Other bits are required to be zero + TU_VERIFY((request->wValue & (~0x7F)) == 0u); // Other bits are required to be zero (USB488v1.0 Table 11) TU_VERIFY(bTag >= 0x02 && bTag <= 127); TU_VERIFY(request->wIndex == usbtmc_state.itf_id); TU_VERIFY(request->wLength == 0x0003); rsp.bTag = (uint8_t)bTag; if(usbtmc_state.ep_int_in != 0) { - rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; - rsp.statusByte = 0x00; // Use interrupt endpoint, instead. - - usbtmc_read_stb_interrupt_488_t intMsg = + rsp.statusByte = 0x00; // Use interrupt endpoint, instead. Must be 0x00 (USB488v1.0 4.3.1.2) + if(usbd_edpt_busy(rhport, usbtmc_state.ep_int_in)) + { + rsp.USBTMC_status = USB488_STATUS_INTERRUPT_IN_BUSY; + } + else { - .bNotify1 = { - .one = 1, - .bTag = bTag & 0x7Fu, - }, - .StatusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)) - }; - // USB488 spec states that transfer must be queued before control request response sent. - usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg, sizeof(intMsg)); + rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + usbtmc_read_stb_interrupt_488_t intMsg = + { + .bNotify1 = { + .one = 1, + .bTag = bTag & 0x7Fu, + }, + .StatusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)) + }; + // Must be queued before control request response sent (USB488v1.0 4.3.1.2) + usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg, sizeof(intMsg)); + } } else { -- cgit v1.3.1 From b9dc9dbd78ee1890342429502d585f323c480fc2 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 11:50:17 +0700 Subject: fix most warnings with rp2040 -wconversion --- examples/device/audio_4_channel_mic/CMakeLists.txt | 3 +++ examples/device/audio_4_channel_mic/src/main.c | 2 +- .../audio_4_channel_mic/src/usb_descriptors.c | 4 ++-- examples/device/audio_test/CMakeLists.txt | 3 +++ examples/device/audio_test/src/main.c | 2 +- examples/device/audio_test/src/usb_descriptors.c | 4 ++-- examples/device/board_test/CMakeLists.txt | 3 +++ examples/device/cdc_dual_ports/CMakeLists.txt | 3 +++ .../device/cdc_dual_ports/src/usb_descriptors.c | 4 ++-- examples/device/cdc_msc/CMakeLists.txt | 3 +++ .../device/cdc_msc_freertos/src/usb_descriptors.c | 4 ++-- examples/device/dfu/CMakeLists.txt | 5 ++++- examples/device/dfu/src/usb_descriptors.c | 2 +- examples/device/dfu_runtime/CMakeLists.txt | 3 +++ examples/device/dfu_runtime/src/usb_descriptors.c | 4 ++-- .../device/dynamic_configuration/CMakeLists.txt | 3 +++ examples/device/dynamic_configuration/src/main.c | 2 +- .../device/dynamic_configuration/src/msc_disk.c | 6 +++--- .../dynamic_configuration/src/usb_descriptors.c | 4 ++-- examples/device/hid_boot_interface/CMakeLists.txt | 3 +++ .../hid_boot_interface/src/usb_descriptors.c | 4 ++-- examples/device/hid_composite/CMakeLists.txt | 3 +++ .../device/hid_composite/src/usb_descriptors.c | 4 ++-- .../hid_composite_freertos/src/usb_descriptors.c | 4 ++-- examples/device/hid_generic_inout/CMakeLists.txt | 3 +++ .../device/hid_generic_inout/src/usb_descriptors.c | 4 ++-- .../device/hid_multiple_interface/CMakeLists.txt | 3 +++ .../hid_multiple_interface/src/usb_descriptors.c | 4 ++-- examples/device/midi_test/CMakeLists.txt | 3 +++ examples/device/midi_test/src/usb_descriptors.c | 4 ++-- examples/device/msc_dual_lun/CMakeLists.txt | 3 +++ examples/device/msc_dual_lun/src/usb_descriptors.c | 4 ++-- examples/device/net_lwip_webserver/CMakeLists.txt | 3 +++ .../net_lwip_webserver/src/usb_descriptors.c | 4 ++-- examples/device/uac2_headset/CMakeLists.txt | 3 +++ examples/device/uac2_headset/src/usb_descriptors.c | 2 +- examples/device/usbtmc/CMakeLists.txt | 3 +++ examples/device/usbtmc/src/usb_descriptors.c | 2 +- examples/device/video_capture/CMakeLists.txt | 3 +++ .../device/video_capture/src/usb_descriptors.c | 4 ++-- examples/device/webusb_serial/CMakeLists.txt | 3 +++ .../device/webusb_serial/src/usb_descriptors.c | 4 ++-- .../host_hid_to_device_cdc/src/usb_descriptors.c | 2 +- examples/example.cmake | 25 ++++++++++++++++++++++ hw/bsp/rp2040/family.c | 6 +++++- src/class/audio/audio_device.c | 2 +- src/class/hid/hid_device.c | 5 +++-- src/class/midi/midi_device.c | 12 +++++------ 48 files changed, 140 insertions(+), 53 deletions(-) create mode 100644 examples/example.cmake (limited to 'src/class') diff --git a/examples/device/audio_4_channel_mic/CMakeLists.txt b/examples/device/audio_4_channel_mic/CMakeLists.txt index f6e10e2ea..e6ce2813e 100644 --- a/examples/device/audio_4_channel_mic/CMakeLists.txt +++ b/examples/device/audio_4_channel_mic/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c index 9c94edd49..a6af5fd19 100644 --- a/examples/device/audio_4_channel_mic/src/main.c +++ b/examples/device/audio_4_channel_mic/src/main.c @@ -221,7 +221,7 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * // Request uses format layout 2 TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); - volume[channelNum] = ((audio_control_cur_2_t*) pBuff)->bCur; + volume[channelNum] = (uint16_t) ((audio_control_cur_2_t*) pBuff)->bCur; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; diff --git a/examples/device/audio_4_channel_mic/src/usb_descriptors.c b/examples/device/audio_4_channel_mic/src/usb_descriptors.c index 93ae2ea47..8929f3057 100644 --- a/examples/device/audio_4_channel_mic/src/usb_descriptors.c +++ b/examples/device/audio_4_channel_mic/src/usb_descriptors.c @@ -149,7 +149,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; for(uint8_t i=0; iwLength == sizeof(audio_control_cur_2_t)); - volume[channelNum] = ((audio_control_cur_2_t*) pBuff)->bCur; + volume[channelNum] = (uint16_t) ((audio_control_cur_2_t*) pBuff)->bCur; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; diff --git a/examples/device/audio_test/src/usb_descriptors.c b/examples/device/audio_test/src/usb_descriptors.c index 09b2a2d45..da3e203d7 100644 --- a/examples/device/audio_test/src/usb_descriptors.c +++ b/examples/device/audio_test/src/usb_descriptors.c @@ -149,7 +149,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; for(uint8_t i=0; i 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -247,7 +247,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/cdc_msc/CMakeLists.txt b/examples/device/cdc_msc/CMakeLists.txt index fa6e83b7e..04c7c1b26 100644 --- a/examples/device/cdc_msc/CMakeLists.txt +++ b/examples/device/cdc_msc/CMakeLists.txt @@ -24,6 +24,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/cdc_msc_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_freertos/src/usb_descriptors.c index 9585822a3..30a712275 100644 --- a/examples/device/cdc_msc_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_freertos/src/usb_descriptors.c @@ -247,7 +247,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -258,7 +258,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/dfu/CMakeLists.txt b/examples/device/dfu/CMakeLists.txt index abc4d91da..121ab3852 100644 --- a/examples/device/dfu/CMakeLists.txt +++ b/examples/device/dfu/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. -family_configure_device_example(${PROJECT}) \ No newline at end of file +family_configure_device_example(${PROJECT}) diff --git a/examples/device/dfu/src/usb_descriptors.c b/examples/device/dfu/src/usb_descriptors.c index 350334aa5..51a0d09f5 100644 --- a/examples/device/dfu/src/usb_descriptors.c +++ b/examples/device/dfu/src/usb_descriptors.c @@ -152,7 +152,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) { chr_count = 31; } diff --git a/examples/device/dfu_runtime/CMakeLists.txt b/examples/device/dfu_runtime/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/dfu_runtime/CMakeLists.txt +++ b/examples/device/dfu_runtime/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/dfu_runtime/src/usb_descriptors.c b/examples/device/dfu_runtime/src/usb_descriptors.c index 060943289..1b0a60551 100644 --- a/examples/device/dfu_runtime/src/usb_descriptors.c +++ b/examples/device/dfu_runtime/src/usb_descriptors.c @@ -147,7 +147,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) { chr_count = 31; } @@ -160,7 +160,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (uint16_t)((((uint16_t)TUSB_DESC_STRING) << 8 ) | (2u*chr_count + 2u)); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/dynamic_configuration/CMakeLists.txt b/examples/device/dynamic_configuration/CMakeLists.txt index fa6e83b7e..04c7c1b26 100644 --- a/examples/device/dynamic_configuration/CMakeLists.txt +++ b/examples/device/dynamic_configuration/CMakeLists.txt @@ -24,6 +24,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/dynamic_configuration/src/main.c b/examples/device/dynamic_configuration/src/main.c index 95f8b8286..33a603343 100644 --- a/examples/device/dynamic_configuration/src/main.c +++ b/examples/device/dynamic_configuration/src/main.c @@ -181,7 +181,7 @@ void midi_task(void) start_ms += 286; // Previous positions in the note sequence. - int previous = note_pos - 1; + int previous = (int) (note_pos - 1); // If we currently are at position 0, set the // previous position to the last note in the sequence. diff --git a/examples/device/dynamic_configuration/src/msc_disk.c b/examples/device/dynamic_configuration/src/msc_disk.c index a895f4738..e8cb03fdd 100644 --- a/examples/device/dynamic_configuration/src/msc_disk.c +++ b/examples/device/dynamic_configuration/src/msc_disk.c @@ -184,7 +184,7 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff uint8_t const* addr = msc_disk[lba] + offset; memcpy(buffer, addr, bufsize); - return bufsize; + return (int32_t) bufsize; } // Callback invoked when received WRITE10 command. @@ -203,7 +203,7 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* (void) lba; (void) offset; (void) buffer; #endif - return bufsize; + return (int32_t) bufsize; } // Callback invoked when received an SCSI command not in built-in list below @@ -237,7 +237,7 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, { if(in_xfer) { - memcpy(buffer, response, resplen); + memcpy(buffer, response, (size_t) resplen); }else { // SCSI output diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index b88f20163..457f774d0 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -226,7 +226,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -237,7 +237,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/hid_boot_interface/CMakeLists.txt b/examples/device/hid_boot_interface/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/hid_boot_interface/CMakeLists.txt +++ b/examples/device/hid_boot_interface/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_boot_interface/src/usb_descriptors.c b/examples/device/hid_boot_interface/src/usb_descriptors.c index 3fa48d98d..a0d7e9f15 100644 --- a/examples/device/hid_boot_interface/src/usb_descriptors.c +++ b/examples/device/hid_boot_interface/src/usb_descriptors.c @@ -163,7 +163,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -174,7 +174,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/hid_composite/CMakeLists.txt b/examples/device/hid_composite/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/hid_composite/CMakeLists.txt +++ b/examples/device/hid_composite/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_composite/src/usb_descriptors.c b/examples/device/hid_composite/src/usb_descriptors.c index e760b20ba..2988baee2 100644 --- a/examples/device/hid_composite/src/usb_descriptors.c +++ b/examples/device/hid_composite/src/usb_descriptors.c @@ -210,7 +210,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -221,7 +221,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/hid_composite_freertos/src/usb_descriptors.c b/examples/device/hid_composite_freertos/src/usb_descriptors.c index 791813fdf..4df12d3db 100644 --- a/examples/device/hid_composite_freertos/src/usb_descriptors.c +++ b/examples/device/hid_composite_freertos/src/usb_descriptors.c @@ -208,7 +208,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -219,7 +219,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/hid_generic_inout/CMakeLists.txt b/examples/device/hid_generic_inout/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/hid_generic_inout/CMakeLists.txt +++ b/examples/device/hid_generic_inout/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_generic_inout/src/usb_descriptors.c b/examples/device/hid_generic_inout/src/usb_descriptors.c index 5dabf42a3..c2b4792c8 100644 --- a/examples/device/hid_generic_inout/src/usb_descriptors.c +++ b/examples/device/hid_generic_inout/src/usb_descriptors.c @@ -153,7 +153,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -164,7 +164,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/hid_multiple_interface/CMakeLists.txt b/examples/device/hid_multiple_interface/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/hid_multiple_interface/CMakeLists.txt +++ b/examples/device/hid_multiple_interface/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_multiple_interface/src/usb_descriptors.c b/examples/device/hid_multiple_interface/src/usb_descriptors.c index 9eef21504..42471a961 100644 --- a/examples/device/hid_multiple_interface/src/usb_descriptors.c +++ b/examples/device/hid_multiple_interface/src/usb_descriptors.c @@ -171,7 +171,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -182,7 +182,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/midi_test/CMakeLists.txt b/examples/device/midi_test/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/midi_test/CMakeLists.txt +++ b/examples/device/midi_test/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index 8444237c6..c84a873b1 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -166,7 +166,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -177,7 +177,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/msc_dual_lun/CMakeLists.txt b/examples/device/msc_dual_lun/CMakeLists.txt index 9e834ae21..518eac3ad 100644 --- a/examples/device/msc_dual_lun/CMakeLists.txt +++ b/examples/device/msc_dual_lun/CMakeLists.txt @@ -24,6 +24,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index 2afd391af..68a671c91 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -168,7 +168,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -179,7 +179,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/net_lwip_webserver/CMakeLists.txt b/examples/device/net_lwip_webserver/CMakeLists.txt index 8e3f0f5a8..5bb091a4f 100644 --- a/examples/device/net_lwip_webserver/CMakeLists.txt +++ b/examples/device/net_lwip_webserver/CMakeLists.txt @@ -69,6 +69,9 @@ if (EXISTS ${TOP}/lib/lwip/src) ${TOP}/lib/networking/rndis_reports.c ) + # Example common such as compiler warnings + include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index 2b4b2a0c3..bee51790a 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -231,7 +231,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > (TU_ARRAY_SIZE(_desc_str) - 1)) chr_count = TU_ARRAY_SIZE(_desc_str) - 1; // Convert ASCII string into UTF-16 @@ -242,7 +242,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/uac2_headset/CMakeLists.txt b/examples/device/uac2_headset/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/uac2_headset/CMakeLists.txt +++ b/examples/device/uac2_headset/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index 9e97845b8..a2d6368bf 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -155,7 +155,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if (chr_count > 31) chr_count = 31; for (uint8_t i = 0; i < chr_count; i++) diff --git a/examples/device/usbtmc/CMakeLists.txt b/examples/device/usbtmc/CMakeLists.txt index c49603c26..74f81b24f 100644 --- a/examples/device/usbtmc/CMakeLists.txt +++ b/examples/device/usbtmc/CMakeLists.txt @@ -24,6 +24,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/usbtmc/src/usb_descriptors.c b/examples/device/usbtmc/src/usb_descriptors.c index 423482634..770a97436 100644 --- a/examples/device/usbtmc/src/usb_descriptors.c +++ b/examples/device/usbtmc/src/usb_descriptors.c @@ -175,7 +175,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) { chr_count = 31; } diff --git a/examples/device/video_capture/CMakeLists.txt b/examples/device/video_capture/CMakeLists.txt index cb321f9a8..416b91665 100644 --- a/examples/device/video_capture/CMakeLists.txt +++ b/examples/device/video_capture/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index da8ec8e89..5c97f4fe1 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -149,7 +149,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -160,7 +160,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/webusb_serial/CMakeLists.txt b/examples/device/webusb_serial/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/webusb_serial/CMakeLists.txt +++ b/examples/device/webusb_serial/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index 93e802a90..cafe2c22b 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -235,7 +235,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -246,7 +246,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c index e55899f65..6b0a89127 100644 --- a/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c +++ b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c @@ -259,7 +259,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/example.cmake b/examples/example.cmake new file mode 100644 index 000000000..6bb82a56d --- /dev/null +++ b/examples/example.cmake @@ -0,0 +1,25 @@ +target_compile_options(${PROJECT} PUBLIC + -Wall + -Wextra + -Werror + -Wfatal-errors + -Wdouble-promotion + #-Wstrict-prototypes + -Wstrict-overflow + #-Werror-implicit-function-declaration + -Wfloat-equal + #-Wundef + -Wshadow + -Wwrite-strings + -Wsign-compare + -Wmissing-format-attribute + -Wunreachable-code + -Wcast-align + -Wcast-function-type + -Wcast-qual + -Wnull-dereference + -Wuninitialized + -Wunused + -Wredundant-decls + -Wconversion + ) diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index 68c9e2d52..90e2192c0 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -53,7 +53,7 @@ // // This doesn't work if others are trying to access flash at the same time, // e.g. XIP streamer, or the other core. -bool __no_inline_not_in_flash_func(get_bootsel_button)() { +bool __no_inline_not_in_flash_func(get_bootsel_button)(void) { const uint CS_PIN_INDEX = 1; // Must disable interrupts, as interrupt handlers may be in flash, and we @@ -170,6 +170,8 @@ void board_init(void) void board_led_write(bool state) { + (void) state; + #ifdef LED_PIN gpio_put(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); #endif @@ -192,6 +194,7 @@ int board_uart_read(uint8_t* buf, int len) } return len; #else + (void) buf; (void) len; return 0; #endif } @@ -205,6 +208,7 @@ int board_uart_write(void const * buf, int len) } return len; #else + (void) buf; (void) len; return 0; #endif } diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index dbd8ab54b..e13e4a46c 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1619,7 +1619,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap #if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING - const uint16_t active_fifo_depth = (audio->tx_supp_ff_sz_max / audio->n_bytes_per_sampe_tx) * audio->n_bytes_per_sampe_tx; + const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / audio->n_bytes_per_sampe_tx) * audio->n_bytes_per_sampe_tx); for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) { tu_fifo_config(&audio->tx_supp_ff[cnt], audio->tx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index cdf155e1c..d15d44838 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -187,7 +187,8 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint1 TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); // len = interface + hid + n*endpoints - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len, 0); // Find available interface @@ -408,7 +409,7 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Received report else if (ep_addr == p_hid->ep_out) { - tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, xferred_bytes); + tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, (uint16_t) xferred_bytes); TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 28e6a92d2..de41706e8 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -127,7 +127,7 @@ uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num) midid_stream_t const* stream = &midi->stream_read; // when using with packet API stream total & index are both zero - return tu_fifo_count(&midi->rx_ff) + (stream->total - stream->index); + return tu_fifo_count(&midi->rx_ff) + (uint8_t) (stream->total - stream->index); } uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize) @@ -179,7 +179,7 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, ui } // Copy data up to bufsize - uint32_t const count = tu_min32(stream->total - stream->index, bufsize); + uint8_t const count = (uint8_t) tu_min32(stream->total - stream->index, bufsize); // Skip the header (1st byte) in the buffer memcpy(buf8, stream->buffer + 1 + stream->index, count); @@ -276,13 +276,13 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* else if ( (msg >= 0x8 && msg <= 0xB) || msg == 0xE ) { // Channel Voice Messages - stream->buffer[0] = (cable_num << 4) | msg; + stream->buffer[0] = (uint8_t) ((cable_num << 4) | msg); stream->total = 4; } else if ( msg == 0xC || msg == 0xD) { // Channel Voice Messages, two-byte variants (Program Change and Channel Pressure) - stream->buffer[0] = (cable_num << 4) | msg; + stream->buffer[0] = (uint8_t) ((cable_num << 4) | msg); stream->total = 3; } else if ( msg == 0xf ) @@ -312,7 +312,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* else { // Pack individual bytes if we don't support packing them into words. - stream->buffer[0] = cable_num << 4 | 0xf; + stream->buffer[0] = (uint8_t) (cable_num << 4 | 0xf); stream->buffer[2] = 0; stream->buffer[3] = 0; stream->index = 2; @@ -513,7 +513,7 @@ bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32 // receive new data if ( ep_addr == p_midi->ep_out ) { - tu_fifo_write_n(&p_midi->rx_ff, p_midi->epout_buf, xferred_bytes); + tu_fifo_write_n(&p_midi->rx_ff, p_midi->epout_buf, (uint16_t) xferred_bytes); // invoke receive callback if available if (tud_midi_rx_cb) tud_midi_rx_cb(itf); -- cgit v1.3.1 From 556b5d5044bd02e89d6b6c6f21e95d46f5fcdfc1 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 12:22:36 +0700 Subject: change report len in hid API from uint8_t to uint16_t since HS interrupt endpoint can be up to 1024, 8-bit is not enough. affected APIs are: - tud_hid_n_report() / tud_hid_report() - tud_hid_report_complete_cb() --- examples/device/hid_boot_interface/src/main.c | 2 +- examples/device/hid_composite/src/main.c | 2 +- examples/device/hid_composite_freertos/src/main.c | 2 +- src/class/hid/hid_device.c | 8 ++++---- src/class/hid/hid_device.h | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/class') diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index 21cdb383d..1958d614d 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -181,7 +181,7 @@ void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint8_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) { (void) instance; (void) report; diff --git a/examples/device/hid_composite/src/main.c b/examples/device/hid_composite/src/main.c index bc2347ab8..3c088b7c2 100644 --- a/examples/device/hid_composite/src/main.c +++ b/examples/device/hid_composite/src/main.c @@ -225,7 +225,7 @@ void hid_task(void) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint8_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) { (void) instance; (void) len; diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index 1030f3d05..ea8d917fe 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -294,7 +294,7 @@ void hid_task(void* param) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint8_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) { (void) instance; (void) len; diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index cdf155e1c..210050858 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -81,7 +81,7 @@ bool tud_hid_n_ready(uint8_t instance) return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in); } -bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint8_t len) +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint16_t len) { uint8_t const rhport = 0; hidd_interface_t * p_hid = &_hidd_itf[instance]; @@ -92,7 +92,7 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, u // prepare data if (report_id) { - len = tu_min8(len, CFG_TUD_HID_EP_BUFSIZE-1); + len = tu_min16(len, CFG_TUD_HID_EP_BUFSIZE-1); p_hid->epin_buf[0] = report_id; memcpy(p_hid->epin_buf+1, report, len); @@ -100,7 +100,7 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, u }else { // If report id = 0, skip ID field - len = tu_min8(len, CFG_TUD_HID_EP_BUFSIZE); + len = tu_min16(len, CFG_TUD_HID_EP_BUFSIZE); memcpy(p_hid->epin_buf, report, len); } @@ -402,7 +402,7 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ { if (tud_hid_report_complete_cb) { - tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint8_t) xferred_bytes); + tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); } } // Received report diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 078b67349..3714d2769 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -62,7 +62,7 @@ uint8_t tud_hid_n_interface_protocol(uint8_t instance); uint8_t tud_hid_n_get_protocol(uint8_t instance); // Send report to host -bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint8_t len); +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint16_t len); // KEYBOARD: convenient helper to send keyboard report if application // use template layout report as defined by hid_keyboard_report_t @@ -82,7 +82,7 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int static inline bool tud_hid_ready(void); static inline uint8_t tud_hid_interface_protocol(void); static inline uint8_t tud_hid_get_protocol(void); -static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len); +static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len); static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]); static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); @@ -116,7 +116,7 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint8_t len); +TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); //--------------------------------------------------------------------+ @@ -137,7 +137,7 @@ static inline uint8_t tud_hid_get_protocol(void) return tud_hid_n_get_protocol(0); } -static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len) +static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len) { return tud_hid_n_report(0, report_id, report, len); } -- cgit v1.3.1 From 6522a8150e22d47bacabd2f1f027452db2254984 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 13:48:47 +0700 Subject: fix all device examples warnings --- examples/device/midi_test/src/main.c | 2 +- examples/device/msc_dual_lun/src/msc_disk_dual.c | 6 ++-- examples/device/uac2_headset/src/main.c | 16 ++++----- examples/device/uac2_headset/src/usb_descriptors.c | 2 +- src/class/audio/audio_device.c | 12 +++++-- src/class/vendor/vendor_device.c | 10 +++--- src/class/video/video_device.c | 38 ++++++++++++---------- 7 files changed, 47 insertions(+), 39 deletions(-) (limited to 'src/class') diff --git a/examples/device/midi_test/src/main.c b/examples/device/midi_test/src/main.c index b47d1af76..3310348bd 100644 --- a/examples/device/midi_test/src/main.c +++ b/examples/device/midi_test/src/main.c @@ -140,7 +140,7 @@ void midi_task(void) start_ms += 286; // Previous positions in the note sequence. - int previous = note_pos - 1; + int previous = (int) (note_pos - 1); // If we currently are at position 0, set the // previous position to the last note in the sequence. diff --git a/examples/device/msc_dual_lun/src/msc_disk_dual.c b/examples/device/msc_dual_lun/src/msc_disk_dual.c index 37446ebc3..2b773b43b 100644 --- a/examples/device/msc_dual_lun/src/msc_disk_dual.c +++ b/examples/device/msc_dual_lun/src/msc_disk_dual.c @@ -277,7 +277,7 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff uint8_t const* addr = (lun ? msc_disk1[lba] : msc_disk0[lba]) + offset; memcpy(buffer, addr, bufsize); - return bufsize; + return (int32_t) bufsize; } bool tud_msc_is_writable_cb (uint8_t lun) @@ -305,7 +305,7 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* (void) lun; (void) lba; (void) offset; (void) buffer; #endif - return bufsize; + return (int32_t) bufsize; } // Callback invoked when received an SCSI command not in built-in list below @@ -339,7 +339,7 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, { if(in_xfer) { - memcpy(buffer, response, resplen); + memcpy(buffer, response, (size_t) resplen); }else { // SCSI output diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index a8d204eaa..003dc2a74 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -159,7 +159,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t { TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate); - audio_control_cur_4_t curf = { tu_htole32(current_sample_rate) }; + audio_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) }; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); } else if (request->bRequest == AUDIO_CS_REQ_RANGE) @@ -171,8 +171,8 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES); for(uint8_t i = 0; i < N_SAMPLE_RATES; i++) { - rangef.subrange[i].bMin = sample_rates[i]; - rangef.subrange[i].bMax = sample_rates[i]; + rangef.subrange[i].bMin = (int32_t) sample_rates[i]; + rangef.subrange[i].bMax = (int32_t) sample_rates[i]; rangef.subrange[i].bRes = 0; TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int)rangef.subrange[i].bMin, (int)rangef.subrange[i].bMax, (int)rangef.subrange[i].bRes); } @@ -204,7 +204,7 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t { TU_VERIFY(request->wLength == sizeof(audio_control_cur_4_t)); - current_sample_rate = ((audio_control_cur_4_t const *)buf)->bCur; + current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *)buf)->bCur; TU_LOG1("Clock set current freq: %ld\r\n", current_sample_rate); @@ -403,9 +403,9 @@ void audio_task(void) // Combine two channels into one int32_t left = *src++; int32_t right = *src++; - *dst++ = (left >> 1) + (right >> 1); + *dst++ = (int16_t) ((left >> 1) + (right >> 1)); } - tud_audio_write((uint8_t *)mic_buf, spk_data_size / 2); + tud_audio_write((uint8_t *)mic_buf, (uint16_t) (spk_data_size / 2)); spk_data_size = 0; } else if (current_resolution == 24) @@ -418,9 +418,9 @@ void audio_task(void) // Combine two channels into one int32_t left = *src++; int32_t right = *src++; - *dst++ = ((left >> 1) + (right >> 1)) & 0xffffff00; + *dst++ = (int32_t) ((uint32_t) ((left >> 1) + (right >> 1)) & 0xffffff00ul); } - tud_audio_write((uint8_t *)mic_buf, spk_data_size / 2); + tud_audio_write((uint8_t *)mic_buf, (uint16_t) (spk_data_size / 2)); spk_data_size = 0; } } diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index a2d6368bf..10f5cbd27 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -165,7 +165,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2 * chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index e13e4a46c..6df68c559 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -537,7 +537,7 @@ tu_fifo_t* tud_audio_n_get_rx_support_ff(uint8_t func_id, uint8_t ff_idx) static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received) { - uint8_t idxItf; + uint8_t idxItf = 0; uint8_t const *dummy2; uint8_t idx_audio_fct = 0; @@ -548,7 +548,10 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t } // Call a weak callback here - a possibility for user to get informed an audio packet was received and data gets now loaded into EP FIFO (or decoded into support RX software FIFO) - if (tud_audio_rx_done_pre_read_cb) TU_VERIFY(tud_audio_rx_done_pre_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); + if (tud_audio_rx_done_pre_read_cb) + { + TU_VERIFY(tud_audio_rx_done_pre_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); + } #if CFG_TUD_AUDIO_ENABLE_DECODING && CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -602,7 +605,10 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t #endif // Call a weak callback here - a possibility for user to get informed decoding was completed - if (tud_audio_rx_done_post_read_cb) TU_VERIFY(tud_audio_rx_done_post_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); + if (tud_audio_rx_done_post_read_cb) + { + TU_VERIFY(tud_audio_rx_done_post_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); + } return true; } diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index c7dfa0062..3b81a108f 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -100,7 +100,7 @@ static void _prep_out_transaction (vendord_interface_t* p_itf) uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize) { vendord_interface_t* p_itf = &_vendord_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_itf->rx_ff, buffer, bufsize); + uint32_t num_read = tu_fifo_read_n(&p_itf->rx_ff, buffer, (uint16_t) bufsize); _prep_out_transaction(p_itf); return num_read; } @@ -133,7 +133,7 @@ static uint16_t maybe_transmit(vendord_interface_t* p_itf) uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) { vendord_interface_t* p_itf = &_vendord_itf[itf]; - uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, bufsize); + uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, (uint16_t) bufsize); if (tu_fifo_count(&p_itf->tx_ff) >= CFG_TUD_VENDOR_EPSIZE) { maybe_transmit(p_itf); } @@ -231,7 +231,7 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui if ( p_vendor->ep_in ) maybe_transmit(p_vendor); } - return (uintptr_t) p_desc - (uintptr_t) desc_itf; + return (uint16_t) ((uintptr_t) p_desc - (uintptr_t) desc_itf); } bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -252,7 +252,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint if ( ep_addr == p_itf->ep_out ) { // Receive new data - tu_fifo_write_n(&p_itf->rx_ff, p_itf->epout_buf, xferred_bytes); + tu_fifo_write_n(&p_itf->rx_ff, p_itf->epout_buf, (uint16_t) xferred_bytes); // Invoked callback if any if (tud_vendor_rx_cb) tud_vendor_rx_cb(itf); @@ -261,7 +261,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint } else if ( ep_addr == p_itf->ep_in ) { - if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, xferred_bytes); + if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); // Send complete, try to send more if possible maybe_transmit(p_itf); } diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 91718f205..7636db5fe 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -297,7 +297,7 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm { tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); uint_fast8_t fmtnum = param->bFormatIndex; - TU_ASSERT(fmtnum <= vs->stm.bNumFormats); + TU_ASSERT(vs && fmtnum <= vs->stm.bNumFormats); if (!fmtnum) { if (1 < vs->stm.bNumFormats) return true; /* Need to negotiate all variables. */ fmtnum = 1; @@ -393,6 +393,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * uint_fast8_t frmnum = param->bFrameIndex; if (!frmnum) { tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); + TU_ASSERT(vs); void const *end = _end_of_streaming_descriptor(vs); tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); switch (request) { @@ -407,15 +408,16 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * break; default: return false; } - param->bFrameIndex = frmnum; + param->bFrameIndex = (uint8_t) frmnum; /* Set the parameters determined by the frame */ tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - param->dwMaxVideoFrameSize = frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8; + param->dwMaxVideoFrameSize = (uint32_t) (frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8); return true; } if (!param->dwFrameInterval) { tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); + TU_ASSERT(vs); void const *end = _end_of_streaming_descriptor(vs); tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); @@ -532,7 +534,7 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t /* Open the notification endpoint */ TU_ASSERT(usbd_edpt_open(rhport, notif)); } - self->cur = (void const*)vc - beg; + self->cur = (uint16_t) ((void const*)vc - beg); return true; } @@ -550,7 +552,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint for (i = 0; i < TU_ARRAY_SIZE(stm->desc.ep); ++i) { uint_fast16_t ofs_ep = stm->desc.ep[i]; if (!ofs_ep) break; - uint_fast8_t ep_adr = _desc_ep_addr(desc + ofs_ep); + uint8_t ep_adr = _desc_ep_addr(desc + ofs_ep); usbd_edpt_close(rhport, ep_adr); stm->desc.ep[i] = 0; TU_LOG2(" close EP%02x\n", ep_adr); @@ -567,7 +569,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint TU_VERIFY(cur < end); uint_fast8_t numeps = ((tusb_desc_interface_t const *)cur)->bNumEndpoints; TU_ASSERT(numeps <= TU_ARRAY_SIZE(stm->desc.ep)); - stm->desc.cur = cur - desc; /* Save the offset of the new settings */ + stm->desc.cur = (uint16_t) (cur - desc); /* Save the offset of the new settings */ if (!altnum) { /* initialize streaming settings */ stm->max_payload_transfer_size = 0; @@ -594,7 +596,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint stm->max_payload_transfer_size = max_size; } TU_ASSERT(usbd_edpt_open(rhport, ep)); - stm->desc.ep[i] = cur - desc; + stm->desc.ep[i] = (uint16_t) (cur - desc); TU_LOG2(" open EP%02x\n", _desc_ep_addr(cur)); } /* initialize payload header */ @@ -976,7 +978,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu /* Find EP address */ void const *desc = _videod_itf[stm->index_vc].beg; - uint_fast8_t ep_addr = 0; + uint8_t ep_addr = 0; for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { uint_fast16_t ofs_ep = stm->desc.ep[i]; if (!ofs_ep) continue; @@ -985,7 +987,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu } if (!ep_addr) return false; - TU_VERIFY( usbd_edpt_claim(0, ep_addr)); + TU_VERIFY( usbd_edpt_claim(0, ep_addr) ); /* update the packet header */ tusb_video_payload_header_t *hdr = (tusb_video_payload_header_t*)stm->ep_buf; hdr->FrameID ^= 1; @@ -994,7 +996,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu stm->buffer = (uint8_t*)buffer; stm->bufsize = bufsize; uint_fast16_t pkt_len = _prepare_in_payload(stm); - TU_ASSERT( usbd_edpt_xfer(0, ep_addr, stm->ep_buf, pkt_len), 0); + TU_ASSERT( usbd_edpt_xfer(0, ep_addr, stm->ep_buf, (uint16_t) pkt_len), 0); return true; } @@ -1034,7 +1036,7 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin /* Find available interface */ videod_interface_t *self = NULL; - uint_fast8_t ctl_idx; + uint8_t ctl_idx; for (ctl_idx = 0; ctl_idx < CFG_TUD_VIDEO; ++ctl_idx) { if (_videod_itf[ctl_idx].beg) continue; self = &_videod_itf[ctl_idx]; @@ -1051,10 +1053,10 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin uint_fast8_t bInCollection = vc->ctl.bInCollection; /* Find the end of the video interface descriptor */ void const *cur = _next_desc_itf(itf_desc, end); - for (uint_fast8_t stm_idx = 0; stm_idx < bInCollection; ++stm_idx) { + for (uint8_t stm_idx = 0; stm_idx < bInCollection; ++stm_idx) { videod_streaming_interface_t *stm = NULL; /* find free streaming interface handle */ - for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { + for (uint8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { if (_videod_streaming_itf[i].desc.beg) continue; stm = &_videod_streaming_itf[i]; self->stm[stm_idx] = i; @@ -1063,12 +1065,12 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin TU_ASSERT(stm, 0); stm->index_vc = ctl_idx; stm->index_vs = stm_idx; - stm->desc.beg = (uintptr_t)cur - (uintptr_t)itf_desc; + stm->desc.beg = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); cur = _next_desc_itf(cur, end); - stm->desc.end = (uintptr_t)cur - (uintptr_t)itf_desc; + stm->desc.end = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); } - self->len = (uintptr_t)cur - (uintptr_t)itf_desc; - return (uintptr_t)cur - (uintptr_t)itf_desc; + self->len = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); + return (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); } // Invoked when a control transfer occurred on an interface of this class @@ -1134,7 +1136,7 @@ bool videod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 /* Claim the endpoint */ TU_VERIFY( usbd_edpt_claim(rhport, ep_addr), 0); uint_fast16_t pkt_len = _prepare_in_payload(stm); - TU_ASSERT( usbd_edpt_xfer(rhport, ep_addr, stm->ep_buf, pkt_len), 0); + TU_ASSERT( usbd_edpt_xfer(rhport, ep_addr, stm->ep_buf, (uint16_t) pkt_len), 0); } else { stm->buffer = NULL; stm->bufsize = 0; -- cgit v1.3.1 From a0ef4898906a5985deae11e5539a942885398ca1 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 17:11:24 +0700 Subject: fix all warnings with host rp2040 --- .../dual/host_hid_to_device_cdc/CMakeLists.txt | 4 + examples/dual/host_hid_to_device_cdc/src/main.c | 6 +- examples/host/bare_api/CMakeLists.txt | 3 + examples/host/bare_api/src/main.c | 11 +- examples/host/cdc_msc_hid/CMakeLists.txt | 3 + examples/host/hid_controller/CMakeLists.txt | 3 + src/class/cdc/cdc_host.c | 8 +- src/class/hid/hid_host.c | 7 +- src/class/msc/msc_host.c | 8 +- src/host/usbh.c | 6 +- src/osal/osal_pico.h | 5 - src/portable/raspberrypi/rp2040/hcd_rp2040.c | 111 +++++++++++---------- 12 files changed, 98 insertions(+), 77 deletions(-) (limited to 'src/class') diff --git a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt index ea4e087e3..cd6f16339 100644 --- a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt +++ b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt @@ -23,6 +23,10 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +# skip extra warnings since pio-usb still has some warnings to fix +#include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_dual_usb_example(${PROJECT}) diff --git a/examples/dual/host_hid_to_device_cdc/src/main.c b/examples/dual/host_hid_to_device_cdc/src/main.c index 6a25a28da..bd7870274 100644 --- a/examples/dual/host_hid_to_device_cdc/src/main.c +++ b/examples/dual/host_hid_to_device_cdc/src/main.c @@ -160,7 +160,7 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re char tempbuf[256]; int count = sprintf(tempbuf, "[%04x:%04x][%u] HID Interface%u, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]); - tud_cdc_write(tempbuf, count); + tud_cdc_write(tempbuf, (uint32_t) count); tud_cdc_write_flush(); // Receive report from boot keyboard & mouse only @@ -179,7 +179,7 @@ void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { char tempbuf[256]; int count = sprintf(tempbuf, "[%u] HID Interface%u is unmounted\r\n", dev_addr, instance); - tud_cdc_write(tempbuf, count); + tud_cdc_write(tempbuf, (uint32_t) count); tud_cdc_write_flush(); } @@ -251,7 +251,7 @@ static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const * re char tempbuf[32]; int count = sprintf(tempbuf, "[%u] %c%c%c %d %d %d\r\n", dev_addr, l, m, r, report->x, report->y, report->wheel); - tud_cdc_write(tempbuf, count); + tud_cdc_write(tempbuf, (uint32_t) count); tud_cdc_write_flush(); } diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt index bc04b01a7..98540ffb0 100644 --- a/examples/host/bare_api/CMakeLists.txt +++ b/examples/host/bare_api/CMakeLists.txt @@ -22,6 +22,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 9ccd856d4..51cab2de0 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -189,7 +189,7 @@ void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* if( TUSB_DESC_INTERFACE != tu_desc_type(p_desc) ) return; tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc; - uint16_t const drv_len = count_interface_total_len(desc_itf, assoc_itf_count, desc_end-p_desc); + uint16_t const drv_len = count_interface_total_len(desc_itf, assoc_itf_count, (uint16_t) (desc_end-p_desc)); // probably corrupted descriptor if(drv_len < sizeof(tusb_desc_interface_t)) return; @@ -244,7 +244,8 @@ void hid_report_received(tuh_xfer_t* xfer); void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { // len = interface + hid + n*endpoints - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); // corrupted descriptor if (max_len < drv_len) return; @@ -377,7 +378,7 @@ static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, ui for (size_t i = 0; i < utf16_len; i++) { uint16_t chr = utf16[i]; if (chr < 0x80) { - *utf8++ = chr & 0xff; + *utf8++ = chr & 0xffu; } else if (chr < 0x800) { *utf8++ = (uint8_t)(0xC0 | (chr >> 6 & 0x1F)); *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); @@ -405,12 +406,12 @@ static int _count_utf8_bytes(const uint16_t *buf, size_t len) { } // TODO: Handle UTF-16 code points that take two entries. } - return total_bytes; + return (int) total_bytes; } static void print_utf16(uint16_t *temp_buf, size_t buf_len) { size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); - size_t utf8_len = _count_utf8_bytes(temp_buf + 1, utf16_len); + size_t utf8_len = (size_t) _count_utf8_bytes(temp_buf + 1, utf16_len); _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len); ((uint8_t*) temp_buf)[utf8_len] = '\0'; diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index c4a4d8e63..6990e957b 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -24,6 +24,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt index 6153d399a..eefeb4a49 100644 --- a/examples/host/hid_controller/CMakeLists.txt +++ b/examples/host/hid_controller/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 044085e81..ee824cb4e 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -105,7 +105,7 @@ bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool i uint8_t const ep_out = cdch_data[dev_addr-1].ep_out; if ( usbh_edpt_busy(dev_addr, ep_out) ) return false; - return usbh_edpt_xfer(dev_addr, ep_out, (void*)(uintptr_t) p_data, length); + return usbh_edpt_xfer(dev_addr, ep_out, (void*)(uintptr_t) p_data, (uint16_t) length); } bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify) @@ -117,7 +117,7 @@ bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is uint8_t const ep_in = cdch_data[dev_addr-1].ep_in; if ( usbh_edpt_busy(dev_addr, ep_in) ) return false; - return usbh_edpt_xfer(dev_addr, ep_in, p_buffer, length); + return usbh_edpt_xfer(dev_addr, ep_in, p_buffer, (uint16_t) length); } bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xfer_cb_t complete_cb) @@ -133,8 +133,8 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xf .direction = TUSB_DIR_OUT }, .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, - .wValue = (rts ? 2 : 0) | (dtr ? 1 : 0), - .wIndex = p_cdc->itf_num, + .wValue = tu_htole16((uint16_t) ((dtr ? 1u : 0u) | (rts ? 2u : 0u))), + .wIndex = tu_htole16(p_cdc->itf_num), .wLength = 0 }; diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 2573f5a6b..ca745464c 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -295,10 +295,10 @@ bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint3 { TU_LOG2(" Get Report callback (%u, %u)\r\n", dev_addr, instance); TU_LOG3_MEM(hid_itf->epin_buf, xferred_bytes, 2); - tuh_hid_report_received_cb(dev_addr, instance, hid_itf->epin_buf, xferred_bytes); + tuh_hid_report_received_cb(dev_addr, instance, hid_itf->epin_buf, (uint16_t) xferred_bytes); }else { - if (tuh_hid_report_sent_cb) tuh_hid_report_sent_cb(dev_addr, instance, hid_itf->epout_buf, xferred_bytes); + if (tuh_hid_report_sent_cb) tuh_hid_report_sent_cb(dev_addr, instance, hid_itf->epout_buf, (uint16_t) xferred_bytes); } return true; @@ -332,7 +332,8 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de TU_LOG2("[%u] HID opening Interface %u\r\n", dev_addr, desc_itf->bInterfaceNumber); // len = interface + hid + n*endpoints - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len); uint8_t const *p_desc = (uint8_t const *) desc_itf; diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index c54a63f37..934f79ff7 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -325,19 +325,19 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 p_msc->stage = MSC_STAGE_DATA; uint8_t const ep_data = (cbw->dir & TUSB_DIR_IN_MASK) ? p_msc->ep_in : p_msc->ep_out; - TU_ASSERT(usbh_edpt_xfer(dev_addr, ep_data, p_msc->buffer, cbw->total_bytes)); + TU_ASSERT(usbh_edpt_xfer(dev_addr, ep_data, p_msc->buffer, (uint16_t) cbw->total_bytes)); }else { // Status stage p_msc->stage = MSC_STAGE_STATUS; - TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, sizeof(msc_csw_t))); + TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t))); } break; case MSC_STAGE_DATA: // Status stage p_msc->stage = MSC_STAGE_STATUS; - TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, sizeof(msc_csw_t))); + TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t))); break; case MSC_STAGE_STATUS: @@ -370,7 +370,7 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); // msc driver length is fixed - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(drv_len <= max_len); msch_interface_t* p_msc = get_itf(dev_addr); diff --git a/src/host/usbh.c b/src/host/usbh.c index 4c9b0b1ba..b6a03b82e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -665,7 +665,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result TU_LOG2_MEM(_ctrl_xfer.buffer, xferred_bytes, 2); } - _ctrl_xfer.actual_len = xferred_bytes; + _ctrl_xfer.actual_len = (uint16_t) xferred_bytes; // ACK stage: toggle is always 1 _set_control_xfer_stage(CONTROL_STAGE_ACK); @@ -696,7 +696,7 @@ bool tuh_edpt_xfer(tuh_xfer_t* xfer) TU_VERIFY(usbh_edpt_claim(daddr, ep_addr)); - if ( !usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, xfer->buflen, xfer->complete_cb, xfer->user_data) ) + if ( !usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, xfer->complete_cb, xfer->user_data) ) { usbh_edpt_release(daddr, ep_addr); return false; @@ -1525,7 +1525,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur } #endif - uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, desc_end-p_desc); + uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, (uint16_t) (desc_end-p_desc)); TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); // Find driver for this interface diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h index abef286b4..8b428d642 100644 --- a/src/osal/osal_pico.h +++ b/src/osal/osal_pico.h @@ -100,11 +100,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd //--------------------------------------------------------------------+ #include "common/tusb_fifo.h" -#if CFG_TUH_ENABLED -extern void hcd_int_disable(uint8_t rhport); -extern void hcd_int_enable(uint8_t rhport); -#endif - typedef struct { tu_fifo_t ff; diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 93c764caf..13e7778ea 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -262,7 +262,7 @@ static struct hw_endpoint *_next_free_interrupt_ep(void) if (!ep->configured) { // Will be configured by _hw_endpoint_init / _hw_endpoint_allocate - ep->interrupt_num = i - 1; + ep->interrupt_num = (uint8_t) (i - 1); return ep; } } @@ -297,7 +297,7 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) return ep; } -static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_addr, uint wMaxPacketSize, uint8_t transfer_type, uint8_t bmInterval) +static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type, uint8_t bmInterval) { // Already has data buffer, endpoint control, and buffer control allocated at this point assert(ep->endpoint_control); @@ -329,7 +329,10 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t | EP_CTRL_INTERRUPT_PER_BUFFER | (ep->transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; - ep_reg |= bmInterval ? (bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB : 0; + if (bmInterval) + { + ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); + } *ep->endpoint_control = ep_reg; pico_trace("endpoint control (0x%p) <- 0x%x\n", ep->endpoint_control, ep_reg); ep->configured = true; @@ -341,7 +344,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t // device address // endpoint number / direction // preamble - uint32_t reg = dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB); + uint32_t reg = (uint32_t) (dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB)); if (dir == TUSB_DIR_OUT) { @@ -367,39 +370,41 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t //--------------------------------------------------------------------+ bool hcd_init(uint8_t rhport) { - pico_trace("hcd_init %d\n", rhport); - assert(rhport == 0); + (void) rhport; + pico_trace("hcd_init %d\n", rhport); + assert(rhport == 0); - // Reset any previous state - rp2040_usb_init(); + // Reset any previous state + rp2040_usb_init(); - // Force VBUS detect to always present, for now we assume vbus is always provided (without using VBUS En) - usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS; + // Force VBUS detect to always present, for now we assume vbus is always provided (without using VBUS En) + usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS; - irq_add_shared_handler(USBCTRL_IRQ, hcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY); + irq_add_shared_handler(USBCTRL_IRQ, hcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY); - // clear epx and interrupt eps - memset(&ep_pool, 0, sizeof(ep_pool)); + // clear epx and interrupt eps + memset(&ep_pool, 0, sizeof(ep_pool)); - // Enable in host mode with SOF / Keep alive on - usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS | USB_MAIN_CTRL_HOST_NDEVICE_BITS; - usb_hw->sie_ctrl = SIE_CTRL_BASE; - usb_hw->inte = USB_INTE_BUFF_STATUS_BITS | - USB_INTE_HOST_CONN_DIS_BITS | - USB_INTE_HOST_RESUME_BITS | - USB_INTE_STALL_BITS | - USB_INTE_TRANS_COMPLETE_BITS | - USB_INTE_ERROR_RX_TIMEOUT_BITS | - USB_INTE_ERROR_DATA_SEQ_BITS ; + // Enable in host mode with SOF / Keep alive on + usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS | USB_MAIN_CTRL_HOST_NDEVICE_BITS; + usb_hw->sie_ctrl = SIE_CTRL_BASE; + usb_hw->inte = USB_INTE_BUFF_STATUS_BITS | + USB_INTE_HOST_CONN_DIS_BITS | + USB_INTE_HOST_RESUME_BITS | + USB_INTE_STALL_BITS | + USB_INTE_TRANS_COMPLETE_BITS | + USB_INTE_ERROR_RX_TIMEOUT_BITS | + USB_INTE_ERROR_DATA_SEQ_BITS ; - return true; + return true; } void hcd_port_reset(uint8_t rhport) { - pico_trace("hcd_port_reset\n"); - assert(rhport == 0); - // TODO: Nothing to do here yet. Perhaps need to reset some state? + (void) rhport; + pico_trace("hcd_port_reset\n"); + assert(rhport == 0); + // TODO: Nothing to do here yet. Perhaps need to reset some state? } void hcd_port_reset_end(uint8_t rhport) @@ -409,25 +414,27 @@ void hcd_port_reset_end(uint8_t rhport) bool hcd_port_connect_status(uint8_t rhport) { - pico_trace("hcd_port_connect_status\n"); - assert(rhport == 0); - return usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS; + (void) rhport; + pico_trace("hcd_port_connect_status\n"); + assert(rhport == 0); + return usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS; } tusb_speed_t hcd_port_speed_get(uint8_t rhport) { - assert(rhport == 0); - // TODO: Should enumval this register - switch (dev_speed()) - { - case 1: - return TUSB_SPEED_LOW; - case 2: - return TUSB_SPEED_FULL; - default: - panic("Invalid speed\n"); - return TUSB_SPEED_INVALID; - } + (void) rhport; + assert(rhport == 0); + // TODO: Should enumval this register + switch (dev_speed()) + { + case 1: + return TUSB_SPEED_LOW; + case 2: + return TUSB_SPEED_FULL; + default: + panic("Invalid speed\n"); + return TUSB_SPEED_INVALID; + } } // Close all opened endpoint belong to this device @@ -465,15 +472,17 @@ uint32_t hcd_frame_number(uint8_t rhport) void hcd_int_enable(uint8_t rhport) { - assert(rhport == 0); - irq_set_enabled(USBCTRL_IRQ, true); + (void) rhport; + assert(rhport == 0); + irq_set_enabled(USBCTRL_IRQ, true); } void hcd_int_disable(uint8_t rhport) { - // todo we should check this is disabling from the correct core; note currently this is never called - assert(rhport == 0); - irq_set_enabled(USBCTRL_IRQ, false); + (void) rhport; + // todo we should check this is disabling from the correct core; note currently this is never called + assert(rhport == 0); + irq_set_enabled(USBCTRL_IRQ, false); } //--------------------------------------------------------------------+ @@ -488,6 +497,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const // Allocated differently based on if it's an interrupt endpoint or not struct hw_endpoint *ep = _hw_endpoint_allocate(ep_desc->bmAttributes.xfer); + TU_ASSERT(ep); _hw_endpoint_init(ep, dev_addr, @@ -510,7 +520,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * // Get appropriate ep. Either EPX or interrupt endpoint struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); - assert(ep); + TU_ASSERT(ep); // EP should be inactive assert(!ep->active); @@ -532,7 +542,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * // That has set up buffer control, endpoint control etc // for host we have to initiate the transfer - usb_hw->dev_addr_ctrl = dev_addr | (ep_num << USB_ADDR_ENDP_ENDPOINT_LSB); + usb_hw->dev_addr_ctrl = (uint32_t) (dev_addr | (ep_num << USB_ADDR_ENDP_ENDPOINT_LSB)); uint32_t flags = USB_SIE_CTRL_START_TRANS_BITS | SIE_CTRL_BASE | (ep_dir ? USB_SIE_CTRL_RECEIVE_DATA_BITS : USB_SIE_CTRL_SEND_DATA_BITS); @@ -556,11 +566,12 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warray-bounds" #pragma GCC diagnostic ignored "-Wstringop-overflow" - memcpy((void*)&usbh_dpram->setup_packet[0], setup_packet, 8); + memcpy((void*) (uintptr_t) &usbh_dpram->setup_packet[0], setup_packet, 8); #pragma GCC diagnostic pop // Configure EP0 struct with setup info for the trans complete struct hw_endpoint *ep = _hw_endpoint_allocate(0); + TU_ASSERT(ep); // EPX should be inactive assert(!ep->active); -- cgit v1.3.1 From 9c56f7011171ff649a821fe87a3ee477299fa860 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 20:30:47 +0700 Subject: suppress error with net example --- examples/device/net_lwip_webserver/CMakeLists.txt | 2 ++ examples/make.mk | 3 ++- src/class/net/ecm_rndis_device.c | 6 +++--- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src/class') diff --git a/examples/device/net_lwip_webserver/CMakeLists.txt b/examples/device/net_lwip_webserver/CMakeLists.txt index beaa9ad99..0f41b888a 100644 --- a/examples/device/net_lwip_webserver/CMakeLists.txt +++ b/examples/device/net_lwip_webserver/CMakeLists.txt @@ -76,6 +76,8 @@ if (EXISTS ${TOP}/lib/lwip/src) target_compile_options(${PROJECT} PUBLIC -Wno-error=null-dereference -Wno-error=conversion + -Wno-error=sign-conversion + -Wno-error=sign-compare ) # Configure compilation flags and libraries for the example... see the corresponding function diff --git a/examples/make.mk b/examples/make.mk index fa909ddca..27e1db38c 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -113,7 +113,8 @@ CFLAGS += \ -Wunused \ -Wredundant-decls -# -Wconversion \ +# conversion is too strict for most mcu driver, may be disable sign/int/arith-conversion +# -Wconversion # Debugging/Optimization ifeq ($(DEBUG), 1) diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c index d85a3f778..5f316762f 100644 --- a/src/class/net/ecm_rndis_device.c +++ b/src/class/net/ecm_rndis_device.c @@ -318,11 +318,11 @@ bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t rndis_generic_msg_t *rndis_msg = (rndis_generic_msg_t *) ((void*) notify.rndis_buf); uint32_t msglen = tu_le32toh(rndis_msg->MessageLength); TU_ASSERT(msglen <= sizeof(notify.rndis_buf)); - tud_control_xfer(rhport, request, notify.rndis_buf, msglen); + tud_control_xfer(rhport, request, notify.rndis_buf, (uint16_t) msglen); } else { - tud_control_xfer(rhport, request, notify.rndis_buf, sizeof(notify.rndis_buf)); + tud_control_xfer(rhport, request, notify.rndis_buf, (uint16_t) sizeof(notify.rndis_buf)); } } break; @@ -369,7 +369,7 @@ static void handle_incoming_packet(uint32_t len) } } - if (!tud_network_recv_cb(pnt, size)) + if (!tud_network_recv_cb(pnt, (uint16_t) size)) { /* if a buffer was never handled by user code, we must renew on the user's behalf */ tud_network_recv_renew(); -- cgit v1.3.1 From 60c1750a9bd79e46385680b35e12f116808894f7 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 30 Jun 2022 22:18:23 +0200 Subject: mimxrt: Add/change definitions for MIMXRT11XX boards. These are mostly identical to the MIMXRT10XX, with one tiny difference. --- hw/bsp/board_mcu.h | 2 +- src/class/audio/audio_device.c | 3 ++- src/common/tusb_mcu.h | 2 +- src/portable/chipidea/ci_hs/ci_hs_imxrt.h | 5 +++++ src/portable/chipidea/ci_hs/dcd_ci_hs.c | 2 +- src/portable/chipidea/ci_hs/hcd_ci_hs.c | 2 +- src/tusb_option.h | 1 + 7 files changed, 12 insertions(+), 5 deletions(-) (limited to 'src/class') diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index 8202479cb..93b1d595f 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -110,7 +110,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI // no header needed -#elif CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#elif CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX #include "fsl_device_registers.h" #elif CFG_TUSB_MCU == OPT_MCU_NUC120 diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 6df68c559..ef0f9c4b7 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -66,7 +66,7 @@ // Use ring buffer if it's available, some MCUs need extra RAM requirements #ifndef TUD_AUDIO_PREFER_RING_BUFFER -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX #define TUD_AUDIO_PREFER_RING_BUFFER 0 #else #define TUD_AUDIO_PREFER_RING_BUFFER 1 @@ -103,6 +103,7 @@ CFG_TUSB_MCU == OPT_MCU_LPC18XX || \ CFG_TUSB_MCU == OPT_MCU_LPC43XX || \ CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ + CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX || \ CFG_TUSB_MCU == OPT_MCU_MSP432E4 #if TUD_AUDIO_PREFER_RING_BUFFER #define USE_LINEAR_BUFFER 0 diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 383a8d686..37866f2a3 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -75,7 +75,7 @@ // TODO USB0 has 5, USB1 has 6 #define TUP_DCD_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) +#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX, OPT_MCU_MIMXRT11XX) #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h index 78ca5a5a2..a2a0c98f4 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h +++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h @@ -29,6 +29,11 @@ #include "fsl_device_registers.h" +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX +#define USB1_BASE USB_OTG1_BASE +#define USB2_BASE USB_OTG2_BASE +#endif + static const ci_hs_controller_t _ci_controller[] = { // RT1010 and RT1020 only has 1 USB controller diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 41d2f1870..0925215ae 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -34,7 +34,7 @@ #include "device/dcd.h" #include "ci_hs_type.h" -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX #include "ci_hs_imxrt.h" #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) #include "ci_hs_lpc18_43.h" diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 221721b0f..39b490f72 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -29,7 +29,7 @@ // Chipidea Highspeed USB IP implement EHCI for host functionality #if CFG_TUH_ENABLED && \ - (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/tusb_option.h b/src/tusb_option.h index 206d23e72..0749a5e52 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -99,6 +99,7 @@ typedef int make_iso_compilers_happy; // NXP iMX RT #define OPT_MCU_MIMXRT10XX 700 ///< NXP iMX RT10xx +#define OPT_MCU_MIMXRT11XX 701 ///< NXP iMX RT11xx // Nuvoton #define OPT_MCU_NUC121 800 -- cgit v1.3.1 From ec6f56768a03fcc43158b0d429e8b826825d02f7 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 1 Jul 2022 08:42:46 +0200 Subject: mimxrt: Change OPT_MCU_MIMXRT1xXX to OPT_MCU_MIMXRT. Which fits both MIMXRT10XX and MIMXRT11XX. --- hw/bsp/board_mcu.h | 2 +- hw/bsp/f1c100s/README.md | 2 +- hw/bsp/imxrt/family.mk | 2 +- src/class/audio/audio_device.c | 5 ++--- src/common/tusb_mcu.h | 2 +- src/portable/chipidea/ci_hs/ci_hs_imxrt.h | 2 +- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 2 +- src/portable/chipidea/ci_hs/hcd_ci_hs.c | 4 ++-- src/portable/nxp/transdimension/dcd_transdimension.c | 6 +++--- src/portable/nxp/transdimension/hcd_transdimension.c | 6 +++--- src/tusb_option.h | 4 ++-- 11 files changed, 18 insertions(+), 19 deletions(-) (limited to 'src/class') diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index 93b1d595f..5c309a21d 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -110,7 +110,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI // no header needed -#elif CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX +#elif CFG_TUSB_MCU == OPT_MCU_MIMXRT #include "fsl_device_registers.h" #elif CFG_TUSB_MCU == OPT_MCU_NUC120 diff --git a/hw/bsp/f1c100s/README.md b/hw/bsp/f1c100s/README.md index 325044716..4aa1e153b 100644 --- a/hw/bsp/f1c100s/README.md +++ b/hw/bsp/f1c100s/README.md @@ -17,4 +17,4 @@ Flash: `make BOARD=f1c100s flash` will write the image to SPI flash, and then re ## TODO -* Add F1C100s to `#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX` high speed MCU check in examples (maybe we should extract the logic?) \ No newline at end of file +* Add F1C100s to `#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT` high speed MCU check in examples (maybe we should extract the logic?) \ No newline at end of file diff --git a/hw/bsp/imxrt/family.mk b/hw/bsp/imxrt/family.mk index 0a55b740b..846ecd255 100644 --- a/hw/bsp/imxrt/family.mk +++ b/hw/bsp/imxrt/family.mk @@ -13,7 +13,7 @@ CFLAGS += \ -D__ARMVFP__=0 -D__ARMFPV5__=0\ -DXIP_EXTERNAL_FLASH=1 \ -DXIP_BOOT_HEADER_ENABLE=1 \ - -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX + -DCFG_TUSB_MCU=OPT_MCU_MIMXRT ifdef BOARD_TUD_RHPORT CFLAGS += -DBOARD_TUD_RHPORT=$(BOARD_TUD_RHPORT) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index ef0f9c4b7..473d1e910 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -66,7 +66,7 @@ // Use ring buffer if it's available, some MCUs need extra RAM requirements #ifndef TUD_AUDIO_PREFER_RING_BUFFER -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT #define TUD_AUDIO_PREFER_RING_BUFFER 0 #else #define TUD_AUDIO_PREFER_RING_BUFFER 1 @@ -102,8 +102,7 @@ CFG_TUSB_MCU == OPT_MCU_GD32VF103 || \ CFG_TUSB_MCU == OPT_MCU_LPC18XX || \ CFG_TUSB_MCU == OPT_MCU_LPC43XX || \ - CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX || \ + CFG_TUSB_MCU == OPT_MCU_MIMXRT || \ CFG_TUSB_MCU == OPT_MCU_MSP432E4 #if TUD_AUDIO_PREFER_RING_BUFFER #define USE_LINEAR_BUFFER 0 diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 37866f2a3..baa82fc14 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -75,7 +75,7 @@ // TODO USB0 has 5, USB1 has 6 #define TUP_DCD_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX, OPT_MCU_MIMXRT11XX) +#elif TU_CHECK_MCU(OPT_MCU_MIMXRT) #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h index a2a0c98f4..53bc8bd00 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h +++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h @@ -29,7 +29,7 @@ #include "fsl_device_registers.h" -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX +#if !defined(USB1_BASE) && defined(USB_OTG1_BASE) #define USB1_BASE USB_OTG1_BASE #define USB2_BASE USB_OTG2_BASE #endif diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 0925215ae..c7cc3e0e8 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -34,7 +34,7 @@ #include "device/dcd.h" #include "ci_hs_type.h" -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT #include "ci_hs_imxrt.h" #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) #include "ci_hs_lpc18_43.h" diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 39b490f72..d0396daea 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -29,7 +29,7 @@ // Chipidea Highspeed USB IP implement EHCI for host functionality #if CFG_TUH_ENABLED && \ - (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX) + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT) //--------------------------------------------------------------------+ // INCLUDE @@ -39,7 +39,7 @@ #include "portable/ehci/ehci_api.h" #include "ci_hs_type.h" -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT #include "ci_hs_imxrt.h" #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) #include "ci_hs_lpc18_43.h" diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c index 2347e1dae..1f27a6872 100644 --- a/src/portable/nxp/transdimension/dcd_transdimension.c +++ b/src/portable/nxp/transdimension/dcd_transdimension.c @@ -27,14 +27,14 @@ #include "tusb_option.h" #if CFG_TUD_ENABLED && \ - (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT) #warning "transdimenion is renamed to chipidea (portable/chipidea/ci_hs) to match other opensource naming convention such as linux. This file will be removed in the future, please update your makefile accordingly" //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT #include "fsl_device_registers.h" #define INCLUDE_FSL_DEVICE_REGISTERS #else @@ -153,7 +153,7 @@ typedef struct const uint8_t ep_count; // Max bi-directional Endpoints }dcd_controller_t; -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT static const dcd_controller_t _dcd_controller[] = { // RT1010 and RT1020 only has 1 USB controller diff --git a/src/portable/nxp/transdimension/hcd_transdimension.c b/src/portable/nxp/transdimension/hcd_transdimension.c index 2d0830981..392764ff6 100644 --- a/src/portable/nxp/transdimension/hcd_transdimension.c +++ b/src/portable/nxp/transdimension/hcd_transdimension.c @@ -29,14 +29,14 @@ // NXP Trans-Dimension USB IP implement EHCI for host functionality #if CFG_TUH_ENABLED && \ - (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT) #warning "transdimenion is renamed to chipidea (portable/chipidea/ci_hs) to match other opensource naming convention such as linux. This file will be removed in the future, please update your makefile accordingly" //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT #include "fsl_device_registers.h" #else // LPCOpen for 18xx & 43xx @@ -58,7 +58,7 @@ typedef struct const IRQn_Type irqnum; // IRQ number }hcd_controller_t; -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT static const hcd_controller_t _hcd_controller[] = { // RT1010 and RT1020 only has 1 USB controller diff --git a/src/tusb_option.h b/src/tusb_option.h index 0749a5e52..a030197f6 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -98,8 +98,8 @@ typedef int make_iso_compilers_happy; #define OPT_MCU_VALENTYUSB_EPTRI 600 ///< Fomu eptri config // NXP iMX RT -#define OPT_MCU_MIMXRT10XX 700 ///< NXP iMX RT10xx -#define OPT_MCU_MIMXRT11XX 701 ///< NXP iMX RT11xx +#define OPT_MCU_MIMXRT 700 ///< NXP iMX RT Series +#define OPT_MCU_MIMXRT10XX OPT_MCU_MIMXRT // Nuvoton #define OPT_MCU_NUC121 800 -- cgit v1.3.1 From 54250d7dd5b22dee07138b925a4ad218a6defcc8 Mon Sep 17 00:00:00 2001 From: NConrad Date: Sat, 9 Jul 2022 17:50:17 -0400 Subject: USBTMC: explicit type conversions fix --- src/class/usbtmc/usbtmc_device.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/class') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index c50ca65d5..af4a92732 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -603,23 +603,23 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request if(ep_addr == usbtmc_state.ep_bulk_out) { criticalEnter(); - usbd_edpt_stall(rhport, ep_addr); - usbd_edpt_clear_stall(rhport, ep_addr); + usbd_edpt_stall(rhport, (uint8_t)ep_addr); + usbd_edpt_clear_stall(rhport, (uint8_t)ep_addr); usbtmc_state.state = STATE_NAK; // USBD core has placed EP in NAK state for us criticalLeave(); tud_usbtmc_bulkOut_clearFeature_cb(); } else if (ep_addr == usbtmc_state.ep_bulk_in) { - usbd_edpt_stall(rhport, ep_addr); - usbd_edpt_clear_stall(rhport, ep_addr); + usbd_edpt_stall(rhport, (uint8_t)ep_addr); + usbd_edpt_clear_stall(rhport, (uint8_t)ep_addr); tud_usbtmc_bulkIn_clearFeature_cb(); } else if ((usbtmc_state.ep_int_in != 0) && (ep_addr == usbtmc_state.ep_int_in)) { // Clearing interrupt in EP - usbd_edpt_stall(rhport, ep_addr); - usbd_edpt_clear_stall(rhport, ep_addr); + usbd_edpt_stall(rhport, (uint8_t)ep_addr); + usbd_edpt_clear_stall(rhport, (uint8_t)ep_addr); } else { -- cgit v1.3.1 From b495d6f8ec263e51b0683ab85ff9e54dab6f5fd3 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 17 Jul 2022 22:46:16 +0700 Subject: temporarily revert len back to uint8_t in tud_hid_report_complete_cb() for up coming release --- examples/device/hid_boot_interface/src/main.c | 2 +- examples/device/hid_composite/src/main.c | 2 +- examples/device/hid_composite_freertos/src/main.c | 2 +- src/class/hid/hid_device.c | 2 +- src/class/hid/hid_device.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/class') diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index 1958d614d..71afa3f46 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -181,7 +181,7 @@ void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, /*uint16_t*/ uint8_t len) { (void) instance; (void) report; diff --git a/examples/device/hid_composite/src/main.c b/examples/device/hid_composite/src/main.c index 05315f266..f7d76cfc7 100644 --- a/examples/device/hid_composite/src/main.c +++ b/examples/device/hid_composite/src/main.c @@ -225,7 +225,7 @@ void hid_task(void) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, /*uint16_t*/ uint8_t len) { (void) instance; (void) len; diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index ea8d917fe..b67c10937 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -294,7 +294,7 @@ void hid_task(void* param) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, /*uint16_t*/ uint8_t len) { (void) instance; (void) len; diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 2d46d760f..8077e4deb 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -403,7 +403,7 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ { if (tud_hid_report_complete_cb) { - tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); + tud_hid_report_complete_cb(instance, p_hid->epin_buf, (/*uint16_t*/ uint8_t) xferred_bytes); } } // Received report diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 3714d2769..3143b1024 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -116,7 +116,7 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); +TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, /*uint16_t*/ uint8_t len ); //--------------------------------------------------------------------+ -- cgit v1.3.1 From c7469ce986b495ccd3777e542df31bd90f4134f2 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 9 Aug 2022 09:53:08 +0200 Subject: dfu: Allow DFU coexistence with other interfaces dfu_moded_open() only works correct when its called on DFU interface descriptor. It means that DFU is the only one interface in configuration or driver is called after all others interface drivers were tried and gave up. If other interface is supported and but driver for DFU is called first (this is the case for BTH and RNDIS). Code after while loop (that was not entered) has an TU_ASSERT that will make set_configuration to fail. Now TU_VERIFY is called first to make sure open code is called for DFU only and not other interface descriptors like in other drivers. --- src/class/dfu/dfu_device.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 8d859d2ee..aa5891ca9 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -167,6 +167,8 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint8_t alt_count = 0; uint16_t drv_len = 0; + TU_VERIFY(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS && itf_desc->bInterfaceProtocol == DFU_PROTOCOL_DFU, 0); + while(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS && itf_desc->bInterfaceProtocol == DFU_PROTOCOL_DFU) { TU_ASSERT(max_len > drv_len, 0); -- cgit v1.3.1 From e80714740ceec841ff4964fe555870cf3ee4f6df Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Tue, 12 Oct 2021 23:29:58 +0900 Subject: Change images to MJPEG --- examples/device/video_capture/src/images.h | 282 +++++++++++++++++++++ examples/device/video_capture/src/main.c | 21 +- .../device/video_capture/src/usb_descriptors.h | 10 +- src/class/video/video.h | 79 ++++++ src/class/video/video_device.c | 175 +++++++++++-- 5 files changed, 536 insertions(+), 31 deletions(-) (limited to 'src/class') diff --git a/examples/device/video_capture/src/images.h b/examples/device/video_capture/src/images.h index 1b13cfe81..33beff662 100644 --- a/examples/device/video_capture/src/images.h +++ b/examples/device/video_capture/src/images.h @@ -1649,3 +1649,285 @@ static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, }; + +#define color_bar_0_jpg_len 511 +#define color_bar_1_jpg_len 512 +#define color_bar_2_jpg_len 511 +#define color_bar_3_jpg_len 511 +#define color_bar_4_jpg_len 511 +#define color_bar_5_jpg_len 512 +#define color_bar_6_jpg_len 511 +#define color_bar_7_jpg_len 511 + +unsigned char color_bar_0_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x92, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0xff, 0xd9 +}; +unsigned char color_bar_1_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x7d, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x7f, 0xff, 0xd9 +}; +unsigned char color_bar_2_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x75, 0x14, 0xcc, + 0xc4, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 +}; +unsigned char color_bar_3_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x5a, 0x2a, 0x08, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x91, 0xff, 0xd9 +}; +unsigned char color_bar_4_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x4a, 0x2a, 0xcb, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x9f, 0xff, 0xd9 +}; +unsigned char color_bar_5_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x6d, 0x14, 0x8d, + 0x04, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x7f, 0xff, 0xd9 +}; +unsigned char color_bar_6_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x65, 0x15, 0xa0, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 +}; +unsigned char color_bar_7_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x8e, 0x8a, 0x00, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9 +}; diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 4028352da..362b168d4 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -110,8 +110,21 @@ static unsigned tx_busy = 0; static unsigned interval_ms = 1000 / FRAME_RATE; /* YUY2 frame buffer */ -#ifdef CFG_EXAMPLE_VIDEO_READONLY +#if 1 #include "images.h" +static struct { + uint32_t size; + uint8_t const *buffer; +} const frames[] = { + {color_bar_0_jpg_len, color_bar_0_jpg}, + {color_bar_1_jpg_len, color_bar_1_jpg}, + {color_bar_2_jpg_len, color_bar_2_jpg}, + {color_bar_3_jpg_len, color_bar_3_jpg}, + {color_bar_4_jpg_len, color_bar_4_jpg}, + {color_bar_5_jpg_len, color_bar_5_jpg}, + {color_bar_6_jpg_len, color_bar_6_jpg}, + {color_bar_7_jpg_len, color_bar_7_jpg}, +}; #else static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8]; static void fill_color_bar(uint8_t *buffer, unsigned start_position) @@ -168,8 +181,7 @@ void video_task(void) already_sent = 1; start_ms = board_millis(); #ifdef CFG_EXAMPLE_VIDEO_READONLY - tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t) &frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], - FRAME_WIDTH * FRAME_HEIGHT * 16/8); + tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frames[frame_num % 8].buffer, frames[frame_num % 8].size); #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); @@ -182,8 +194,7 @@ void video_task(void) start_ms += interval_ms; #ifdef CFG_EXAMPLE_VIDEO_READONLY - tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t) &frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], - FRAME_WIDTH * FRAME_HEIGHT * 16/8); + tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frames[frame_num % 8].buffer, frames[frame_num % 8].size); #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index 90537aa06..aa937e168 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -90,17 +90,17 @@ enum { /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ /* Video stream format */ \ - TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ - /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + 1, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ - TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ _width * _height * 16, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ diff --git a/src/class/video/video.h b/src/class/video/video.h index 844746546..e8227ea60 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -302,6 +302,45 @@ typedef struct TU_ATTR_PACKED { uint8_t bCopyProtect; } tusb_desc_cs_video_fmt_uncompressed_t; +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFormatIndex; + uint8_t bNumFrameDescriptors; + uint8_t bmFlags; + uint8_t bDefaultFrameIndex; + uint8_t bAspectRatioX; + uint8_t bAspectRatioY; + uint8_t bmInterlaceFlags; + uint8_t bCopyProtect; +} tusb_desc_cs_video_fmt_mjpeg_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFormatIndex; + uint32_t dwMaxVideoFrameBufferSize; /* deprecated */ + uint8_t bFormatType; +} tusb_desc_cs_video_fmt_dv_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFormatIndex; + uint8_t bNumFrameDescriptors; + uint8_t guidFormat[16]; + uint8_t bBitsPerPixel; + uint8_t bDefaultFrameIndex; + uint8_t bAspectRatioX; + uint8_t bAspectRatioY; + uint8_t bmInterlaceFlags; + uint8_t bCopyProtect; + uint8_t bVaribaleSize; +} tusb_desc_cs_video_fmt_frame_based_t; + typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -318,6 +357,24 @@ typedef struct TU_ATTR_PACKED { uint32_t dwFrameInterval[]; } tusb_desc_cs_video_frm_uncompressed_t; +typedef tusb_desc_cs_video_frm_uncompressed_t tusb_desc_cs_video_frm_mjpeg_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFrameIndex; + uint8_t bmCapabilities; + uint16_t wWidth; + uint16_t wHeight; + uint32_t dwMinBitRate; + uint32_t dwMaxBitRate; + uint32_t dwDefaultFrameInterval; + uint8_t bFrameIntervalType; + uint32_t dwBytesPerLine; + uint32_t dwFrameInterval[]; +} tusb_desc_cs_video_frm_frame_based_t; + //--------------------------------------------------------------------+ // Requests //--------------------------------------------------------------------+ @@ -378,8 +435,11 @@ TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not c #define TUD_VIDEO_DESC_CS_VS_IN_LEN 13 #define TUD_VIDEO_DESC_CS_VS_OUT_LEN 9 #define TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN 27 +#define TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN 11 #define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN 38 #define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_DISC_LEN 26 +#define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN 38 +#define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC_LEN 26 #define TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN 6 /* 2.2 compression formats */ @@ -462,6 +522,25 @@ TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not c _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ +/* Motion-JPEG 3.1.1 Table 3-1 */ +#define TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(_fmtidx, _numfrmdesc, _fixed_sz, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FORMAT_MJPEG, \ + _fmtidx, _numfrmdesc, _fixed_sz, _frmidx, _asrx, _asry, _interlace, _cp + +/* Motion-JPEG 3.1.1 Table 3-2 and 3-3 */ +#define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, _minfrminterval, _maxfrminterval, _frmintervalstep) \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_MJPEG, \ + _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ + U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), 0, \ + U32_TO_U8S_LE(_minfrminterval), U32_TO_U8S_LE(_maxfrminterval), U32_TO_U8S_LE(_frmintervalstep) + +/* Motion-JPEG 3.1.1 Table 3-2 and 3-4 */ +#define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, ...) \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC_LEN + (TU_ARGS_NUM(__VA_ARGS__)) * 4, \ + TUSB_DESC_CS_INTERFACE, VIDEO_CS_VS_INTERFACE_FRAME_MJPEG, \ + _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ + U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ + /* 3.9.2.6 */ #define TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(_color, _trns, _mat) \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN, \ diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 7636db5fe..39e2e9aac 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -29,6 +29,8 @@ #if (CFG_TUD_ENABLED && CFG_TUD_VIDEO && CFG_TUD_VIDEO_STREAMING) +#include + #include "device/usbd.h" #include "device/usbd_pvt.h" @@ -59,6 +61,30 @@ typedef struct TU_ATTR_PACKED { uint8_t bEntityId; } tusb_desc_cs_video_entity_itf_t; +typedef union { + struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFormatIndex; + }; + tusb_desc_cs_video_fmt_uncompressed_t uncompressed; + tusb_desc_cs_video_fmt_mjpeg_t mjpeg; + tusb_desc_cs_video_fmt_frame_based_t frame_based; +} tusb_desc_cs_video_fmt_t; + +typedef union { + struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFrameIndex; + }; + tusb_desc_cs_video_frm_uncompressed_t uncompressed; + tusb_desc_cs_video_frm_mjpeg_t mjpeg; + tusb_desc_cs_video_frm_frame_based_t frame_based; +} tusb_desc_cs_video_frm_t; + /* video streaming interface */ typedef struct TU_ATTR_PACKED { uint8_t index_vc; /* index of bound video control interface */ @@ -167,6 +193,72 @@ static void const* _find_desc(void const *beg, void const *end, uint_fast8_t des return cur; } +/** Find the first descriptor of a given types + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * @param[in] ... The target descriptor types. The last type must be 0. + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _find_desc_n(void const *beg, void const *end, ...) +{ + uint_fast8_t target = 0; + void const *cur; + for (cur = beg; cur < end && !target; cur = tu_desc_next(cur)) { + uint_fast8_t actual = tu_desc_type(cur); + va_list ap; + va_start(ap, end); + do { + target = va_arg(ap, unsigned); + } while (target && target != actual); + va_end(ap); + } + return cur; +} + +/** Find the first descriptor specified by the arguments + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * @param[in] sub_types The target bDescriptorSubtype list. The last elemnt must be 0. + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _find_desc_cs(void const *beg, void const *end, uint8_t const *sub_types) +{ + uint_fast8_t target = 0; + void const *cur; + for (cur = beg; cur < end && !target; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { + uint_fast8_t actual = ((uint8_t const *)cur)[2]; + uint8_t const *p = sub_types; + do { + target = *p++; + } while (target && target != actual); + } + return cur; +} + +/** Find the first descriptor specified by the arguments + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * @param[in] desc_type The target descriptor type + * @param[in] element_0 The target element following the desc_type + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _find_desc_2(void const *beg, void const *end, + uint_fast8_t desc_type, uint_fast8_t element_0) +{ + for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, desc_type)) { + uint8_t const *p = (uint8_t const *)cur; + if (p[2] == element_0) return cur; + cur = tu_desc_next(cur); + } + return end; +} + /** Find the first descriptor specified by the arguments * * @param[in] beg The head of descriptor byte array. @@ -235,14 +327,19 @@ static inline void const* _find_desc_itf(void const *beg, void const *end, uint_ * @retval end did not found endpoint descriptor */ static void const* _find_desc_ep(void const *beg, void const *end) { - for (void const *cur = beg; cur < end; cur = tu_desc_next(cur)) { - uint_fast8_t desc_type = tu_desc_type(cur); - if (TUSB_DESC_ENDPOINT == desc_type) return cur; - if (TUSB_DESC_INTERFACE == desc_type) break; - } + void const *cur = _find_desc_n(beg, end, TUSB_DESC_ENDPOINT, TUSB_DESC_INTERFACE, 0); + if ((cur < end) && (TUSB_DESC_ENDPOINT == tu_desc_type(cur))) + return cur; return end; } +/** Return the end of the video control descriptor. */ +static inline void const* _end_of_control_descriptor(void const *desc) +{ + tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const *)desc; + return desc + vc->std.bLength + vc->ctl.wTotalLength; +} + /** Find the first entity descriptor with the entity ID * specified by the argument belonging to the current video control descriptor. * @@ -253,10 +350,8 @@ static void const* _find_desc_ep(void const *beg, void const *end) * @retval end did not found interface descriptor */ static void const* _find_desc_entity(void const *desc, uint_fast8_t entityid) { - tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const*)desc; - void const *beg = vc; - void const *end = beg + vc->std.bLength + vc->ctl.wTotalLength; - for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { + void const *end = _end_of_control_descriptor(desc); + for (void const *cur = desc; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { tusb_desc_cs_video_entity_itf_t const *itf = (tusb_desc_cs_video_entity_itf_t const *)cur; if ((VIDEO_CS_ITF_VC_INPUT_TERMINAL <= itf->bDescriptorSubtype && itf->bDescriptorSubtype < VIDEO_CS_ITF_VC_MAX) @@ -276,17 +371,38 @@ static inline void const* _end_of_streaming_descriptor(void const *desc) } /** Find the first format descriptor with the specified format number. */ -static inline tusb_desc_cs_video_fmt_uncompressed_t const *_find_desc_format(void const *beg, void const *end, uint_fast8_t fmtnum) +static inline void const *_find_desc_format(void const *beg, void const *end, uint_fast8_t fmtnum) { - return (tusb_desc_cs_video_fmt_uncompressed_t const*) - _find_desc_3(beg, end, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, fmtnum); + static uint8_t const sub_types[] = { + VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, + VIDEO_CS_ITF_VS_FORMAT_MJPEG, + VIDEO_CS_ITF_VS_FORMAT_DV, + VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED, + 0 + }; + while (true) { + uint8_t const *cur = _find_desc_cs(beg, end, sub_types); + if ((end == cur) || (fmtnum == cur[3])) + return cur; + cur = tu_desc_next(cur); + } } /** Find the first frame descriptor with the specified format number. */ -static inline tusb_desc_cs_video_frm_uncompressed_t const *_find_desc_frame(void const *beg, void const *end, uint_fast8_t frmnum) +static inline void const *_find_desc_frame(void const *beg, void const *end, uint_fast8_t frmnum) { - return (tusb_desc_cs_video_frm_uncompressed_t const*) - _find_desc_3(beg, end, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, frmnum); + static uint8_t const sub_types[] = { + VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, + VIDEO_CS_ITF_VS_FRAME_MJPEG, + VIDEO_CS_ITF_VS_FRAME_FRAME_BASED, + 0 + }; + while (true) { + uint8_t const *cur = _find_desc_cs(beg, end, sub_types); + if ((end == cur) || (frmnum == ((uint8_t const *)cur)[3])) + return cur; + cur = tu_desc_next(cur); + } } /** Set uniquely determined values to variables that have not been set @@ -307,7 +423,6 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm /* Set the parameters determined by the format */ param->wKeyFrameRate = 1; param->wPFrameRate = 0; - param->wCompQuality = 1; /* 1 to 10000 */ param->wCompWindowSize = 1; /* GOP size? */ param->wDelay = 0; /* milliseconds */ param->dwClockFrequency = 27000000; /* same as MPEG-2 system time clock */ @@ -319,8 +434,18 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm param->bBitDepthLuma = 8; void const *end = _end_of_streaming_descriptor(vs); - tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); + tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); TU_ASSERT(fmt != end); + + switch (fmt->bDescriptorSubtype) { + case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: + param->wCompQuality = 1; /* 1 to 10000 */ + break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG; + break; + default: return false; + } + uint_fast8_t frmnum = param->bFrameIndex; TU_ASSERT(frmnum <= fmt->bNumFrameDescriptors); if (!frmnum) { @@ -328,13 +453,21 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm frmnum = 1; param->bFrameIndex = 1; } - tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); + tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); TU_ASSERT(frm != end); /* Set the parameters determined by the frame */ uint_fast32_t frame_size = param->dwMaxVideoFrameSize; if (!frame_size) { - frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8; + switch (fmt->bDescriptorSubtype) { + case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: + frame_size = (uint_fast32_t)frm->uncompressed.wWidth * frm->uncompressed.wHeight * fmt->uncompressed.bBitsPerPixel / 8; + break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG; + frame_size = (uint_fast32_t)frm->mjpeg.wWidth * frm->mjpeg.wHeight * 16 / 8; /* YUV422 */ + break; + default: break; + } param->dwMaxVideoFrameSize = frame_size; } @@ -487,7 +620,7 @@ static bool _close_vc_itf(uint8_t rhport, videod_interface_t *self) /* The next descriptor after the class-specific VC interface header descriptor. */ void const *cur = (void const*)vc + vc->std.bLength + vc->ctl.bLength; /* The end of the video control interface descriptor. */ - void const *end = (void const*)vc + vc->std.bLength + vc->ctl.wTotalLength; + void const *end = _end_of_control_descriptor(vc); if (vc->std.bNumEndpoints) { /* Find the notification endpoint descriptor. */ cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT); @@ -519,7 +652,7 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t TU_ASSERT(vc->ctl.bInCollection <= CFG_TUD_VIDEO_STREAMING); /* Update to point the end of the video control interface descriptor. */ - end = cur + vc->std.bLength + vc->ctl.wTotalLength; + end = _end_of_control_descriptor(cur); /* Advance to the next descriptor after the class-specific VC interface header descriptor. */ cur += vc->std.bLength + vc->ctl.bLength; TU_LOG2(" bNumEndpoints %d\n", vc->std.bNumEndpoints); -- cgit v1.3.1 From 1debf6270786a612ad99172db76169e025e124f6 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Wed, 10 Nov 2021 00:39:51 +0900 Subject: Fix compile errors --- .../device/video_capture/src/usb_descriptors.h | 6 +++--- src/class/video/video_device.c | 24 +++++++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'src/class') diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index aa937e168..10bae4750 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -53,8 +53,8 @@ enum { /* Interface 1, Alternate 0 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ - + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ /* Interface 1, Alternate 1 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ @@ -98,7 +98,7 @@ enum { /*bmaControls(1)*/0), \ /* Video stream format */ \ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ - 1, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 39e2e9aac..14eaca9a4 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -67,6 +67,7 @@ typedef union { uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; + uint8_t bNumFrameDescriptors; }; tusb_desc_cs_video_fmt_uncompressed_t uncompressed; tusb_desc_cs_video_fmt_mjpeg_t mjpeg; @@ -437,11 +438,11 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); TU_ASSERT(fmt != end); - switch (fmt->bDescriptorSubtype) { + switch (fmt->bDescriptorSubType) { case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: param->wCompQuality = 1; /* 1 to 10000 */ break; - case VIDEO_CS_ITF_VS_FORMAT_MJPEG; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: break; default: return false; } @@ -459,11 +460,11 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm /* Set the parameters determined by the frame */ uint_fast32_t frame_size = param->dwMaxVideoFrameSize; if (!frame_size) { - switch (fmt->bDescriptorSubtype) { + switch (fmt->bDescriptorSubType) { case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: frame_size = (uint_fast32_t)frm->uncompressed.wWidth * frm->uncompressed.wHeight * fmt->uncompressed.bBitsPerPixel / 8; break; - case VIDEO_CS_ITF_VS_FORMAT_MJPEG; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: frame_size = (uint_fast32_t)frm->mjpeg.wWidth * frm->mjpeg.wHeight * 16 / 8; /* YUV422 */ break; default: break; @@ -473,11 +474,12 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm uint_fast32_t interval = param->dwFrameInterval; if (!interval) { - if ((1 < frm->bFrameIntervalType) || - ((0 == frm->bFrameIntervalType) && (frm->dwFrameInterval[1] != frm->dwFrameInterval[0]))) { + if ((1 < frm->uncompressed.bFrameIntervalType) || + ((0 == frm->uncompressed.bFrameIntervalType) && + (frm->uncompressed.dwFrameInterval[1] != frm->uncompressed.dwFrameInterval[0]))) { return true; } - interval = frm->dwFrameInterval[0]; + interval = frm->uncompressed.dwFrameInterval[0]; param->dwFrameInterval = interval; } uint_fast32_t interval_ms = interval / 10000; @@ -709,6 +711,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint video_probe_and_commit_control_t *param = (video_probe_and_commit_control_t *)&stm->ep_buf; tu_memclr(param, sizeof(*param)); + TU_LOG2(" done 0\n"); return _update_streaming_parameters(stm, param); } /* Open endpoints of the new settings. */ @@ -737,6 +740,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint hdr->bHeaderLength = sizeof(*hdr); hdr->bmHeaderInfo = 0; + TU_LOG2(" done\n"); return true; } @@ -809,7 +813,7 @@ static int handle_video_ctl_cs_req(uint8_t rhport, uint8_t stage, if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, &self->power_mode, sizeof(self->power_mode)), VIDEO_ERROR_UNKNOWN); - } else if (stage == CONTROL_STAGE_ACK) { + } else if (stage == CONTROL_STAGE_DATA) { if (tud_video_power_mode_cb) return tud_video_power_mode_cb(ctl_idx, self->power_mode); } return VIDEO_ERROR_NONE; @@ -954,7 +958,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, TU_VERIFY(sizeof(video_probe_and_commit_control_t) == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); - } else if (stage == CONTROL_STAGE_ACK) { + } else if (stage == CONTROL_STAGE_DATA) { TU_VERIFY(_update_streaming_parameters(self, (video_probe_and_commit_control_t*)self->ep_buf), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); } @@ -1009,7 +1013,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(sizeof(video_probe_and_commit_control_t) == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); - } else if (stage == CONTROL_STAGE_ACK) { + } else if (stage == CONTROL_STAGE_DATA) { TU_VERIFY(_update_streaming_parameters(self, (video_probe_and_commit_control_t*)self->ep_buf), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); if (tud_video_commit_cb) { return tud_video_commit_cb(self->index_vc, self->index_vs, (video_probe_and_commit_control_t*)self->ep_buf); -- cgit v1.3.1 From 6c3c2df82343e1947a7be3c5f0e72a116c1b634e Mon Sep 17 00:00:00 2001 From: Mark K Cowan Date: Sat, 17 Sep 2022 21:27:04 +0300 Subject: audio_device: prototype added for function referenced before use --- src/class/audio/audio_device.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a021755ba..a65d605b7 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -447,6 +447,10 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +static bool set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq); +#endif + bool tud_audio_n_mounted(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO); -- cgit v1.3.1 From ee832e4e37a0ea35d9c2751ee3600ae7a600cb12 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 3 Oct 2022 21:41:58 +0900 Subject: Fix descriptor searching --- src/class/video/video_device.c | 121 ++++++++++------------------------------- 1 file changed, 28 insertions(+), 93 deletions(-) (limited to 'src/class') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 14eaca9a4..690e64658 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -29,8 +29,6 @@ #if (CFG_TUD_ENABLED && CFG_TUD_VIDEO && CFG_TUD_VIDEO_STREAMING) -#include - #include "device/usbd.h" #include "device/usbd_pvt.h" @@ -194,72 +192,6 @@ static void const* _find_desc(void const *beg, void const *end, uint_fast8_t des return cur; } -/** Find the first descriptor of a given types - * - * @param[in] beg The head of descriptor byte array. - * @param[in] end The tail of descriptor byte array. - * @param[in] ... The target descriptor types. The last type must be 0. - * - * @return The pointer for interface descriptor. - * @retval end did not found interface descriptor */ -static void const* _find_desc_n(void const *beg, void const *end, ...) -{ - uint_fast8_t target = 0; - void const *cur; - for (cur = beg; cur < end && !target; cur = tu_desc_next(cur)) { - uint_fast8_t actual = tu_desc_type(cur); - va_list ap; - va_start(ap, end); - do { - target = va_arg(ap, unsigned); - } while (target && target != actual); - va_end(ap); - } - return cur; -} - -/** Find the first descriptor specified by the arguments - * - * @param[in] beg The head of descriptor byte array. - * @param[in] end The tail of descriptor byte array. - * @param[in] sub_types The target bDescriptorSubtype list. The last elemnt must be 0. - * - * @return The pointer for interface descriptor. - * @retval end did not found interface descriptor */ -static void const* _find_desc_cs(void const *beg, void const *end, uint8_t const *sub_types) -{ - uint_fast8_t target = 0; - void const *cur; - for (cur = beg; cur < end && !target; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { - uint_fast8_t actual = ((uint8_t const *)cur)[2]; - uint8_t const *p = sub_types; - do { - target = *p++; - } while (target && target != actual); - } - return cur; -} - -/** Find the first descriptor specified by the arguments - * - * @param[in] beg The head of descriptor byte array. - * @param[in] end The tail of descriptor byte array. - * @param[in] desc_type The target descriptor type - * @param[in] element_0 The target element following the desc_type - * - * @return The pointer for interface descriptor. - * @retval end did not found interface descriptor */ -static void const* _find_desc_2(void const *beg, void const *end, - uint_fast8_t desc_type, uint_fast8_t element_0) -{ - for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, desc_type)) { - uint8_t const *p = (uint8_t const *)cur; - if (p[2] == element_0) return cur; - cur = tu_desc_next(cur); - } - return end; -} - /** Find the first descriptor specified by the arguments * * @param[in] beg The head of descriptor byte array. @@ -328,9 +260,11 @@ static inline void const* _find_desc_itf(void const *beg, void const *end, uint_ * @retval end did not found endpoint descriptor */ static void const* _find_desc_ep(void const *beg, void const *end) { - void const *cur = _find_desc_n(beg, end, TUSB_DESC_ENDPOINT, TUSB_DESC_INTERFACE, 0); - if ((cur < end) && (TUSB_DESC_ENDPOINT == tu_desc_type(cur))) - return cur; + for (void const *cur = beg; cur < end; cur = tu_desc_next(cur)) { + uint_fast8_t desc_type = tu_desc_type(cur); + if (TUSB_DESC_ENDPOINT == desc_type) return cur; + if (TUSB_DESC_INTERFACE == desc_type) break; + } return end; } @@ -374,36 +308,36 @@ static inline void const* _end_of_streaming_descriptor(void const *desc) /** Find the first format descriptor with the specified format number. */ static inline void const *_find_desc_format(void const *beg, void const *end, uint_fast8_t fmtnum) { - static uint8_t const sub_types[] = { - VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, - VIDEO_CS_ITF_VS_FORMAT_MJPEG, - VIDEO_CS_ITF_VS_FORMAT_DV, - VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED, - 0 - }; - while (true) { - uint8_t const *cur = _find_desc_cs(beg, end, sub_types); - if ((end == cur) || (fmtnum == cur[3])) + for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { + uint8_t const *p = (uint8_t const *)cur; + uint_fast8_t fmt = p[2]; + if ((fmt == VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED || + fmt == VIDEO_CS_ITF_VS_FORMAT_MJPEG || + fmt == VIDEO_CS_ITF_VS_FORMAT_DV || + fmt == VIDEO_CS_ITF_VS_FRAME_FRAME_BASED) && + fmtnum == p[3]) { return cur; + } cur = tu_desc_next(cur); } + return end; } /** Find the first frame descriptor with the specified format number. */ static inline void const *_find_desc_frame(void const *beg, void const *end, uint_fast8_t frmnum) { - static uint8_t const sub_types[] = { - VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, - VIDEO_CS_ITF_VS_FRAME_MJPEG, - VIDEO_CS_ITF_VS_FRAME_FRAME_BASED, - 0 - }; - while (true) { - uint8_t const *cur = _find_desc_cs(beg, end, sub_types); - if ((end == cur) || (frmnum == ((uint8_t const *)cur)[3])) + for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { + uint8_t const *p = (uint8_t const *)cur; + uint_fast8_t frm = p[2]; + if ((frm == VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED || + frm == VIDEO_CS_ITF_VS_FRAME_MJPEG || + frm == VIDEO_CS_ITF_VS_FRAME_FRAME_BASED) && + frmnum == p[3]) { return cur; + } cur = tu_desc_next(cur); } + return end; } /** Set uniquely determined values to variables that have not been set @@ -501,7 +435,8 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * if (!fmtnum) { switch (request) { case VIDEO_REQUEST_GET_MAX: - param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats; + if (_get_desc_vs(stm)) + param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats; break; case VIDEO_REQUEST_GET_MIN: case VIDEO_REQUEST_GET_DEF: @@ -982,7 +917,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, video_probe_and_commit_control_t tmp; tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; TU_VERIFY(_negotiate_streaming_parameters(self, request->bRequest, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); - TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, &tmp, sizeof(tmp)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; @@ -999,7 +934,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); - TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t)&_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; -- cgit v1.3.1 From 4be7ffd63f972e241325355d239c44e472dc56dc Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Fri, 7 Oct 2022 21:30:03 +0900 Subject: Fix max payload size to clip at 1023 --- src/class/video/video_device.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/class') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 690e64658..a96bee617 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -419,6 +419,8 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm uint_fast32_t interval_ms = interval / 10000; TU_ASSERT(interval_ms); uint_fast32_t payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; + if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) + payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; param->dwMaxPayloadTransferSize = payload_size; return true; } @@ -478,10 +480,10 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * break; default: return false; } - param->bFrameIndex = (uint8_t) frmnum; + param->bFrameIndex = (uint8_t)frmnum; /* Set the parameters determined by the frame */ tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - param->dwMaxVideoFrameSize = (uint32_t) (frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8); + param->dwMaxVideoFrameSize = (uint32_t)(frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8); return true; } @@ -536,11 +538,15 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * param->dwMaxPayloadTransferSize = 0; } else { uint_fast32_t frame_size = param->dwMaxVideoFrameSize; + uint_fast32_t payload_size; if (!interval_ms) { - param->dwMaxPayloadTransferSize = frame_size + 2; + payload_size = frame_size + 2; } else { - param->dwMaxPayloadTransferSize = (frame_size + interval_ms - 1) / interval_ms + 2; + payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; } + if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) + payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; + param->dwMaxPayloadTransferSize = payload_size; } return true; } -- cgit v1.3.1 From 53dc9d55b57faa3199711fe82b47195d0369c1d8 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Wed, 12 Oct 2022 20:41:03 +0900 Subject: Fix pointer type to calculate streaming parameter --- src/class/video/video_device.c | 63 ++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 21 deletions(-) (limited to 'src/class') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index a96bee617..a6d2724c1 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -74,10 +74,13 @@ typedef union { typedef union { struct TU_ATTR_PACKED { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubType; - uint8_t bFrameIndex; + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFrameIndex; + uint8_t bmCapabilities; + uint16_t wWidth; + uint16_t wHeight; }; tusb_desc_cs_video_frm_uncompressed_t uncompressed; tusb_desc_cs_video_frm_mjpeg_t mjpeg; @@ -396,10 +399,10 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm if (!frame_size) { switch (fmt->bDescriptorSubType) { case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: - frame_size = (uint_fast32_t)frm->uncompressed.wWidth * frm->uncompressed.wHeight * fmt->uncompressed.bBitsPerPixel / 8; + frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->uncompressed.bBitsPerPixel / 8; break; case VIDEO_CS_ITF_VS_FORMAT_MJPEG: - frame_size = (uint_fast32_t)frm->mjpeg.wWidth * frm->mjpeg.wHeight * 16 / 8; /* YUV422 */ + frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ break; default: break; } @@ -467,7 +470,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); TU_ASSERT(vs); void const *end = _end_of_streaming_descriptor(vs); - tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); + tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); switch (request) { case VIDEO_REQUEST_GET_MAX: frmnum = fmt->bNumFrameDescriptors; @@ -476,14 +479,32 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * frmnum = 1; break; case VIDEO_REQUEST_GET_DEF: - frmnum = fmt->bDefaultFrameIndex; + switch (fmt->bDescriptorSubType) { + case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: + frmnum = fmt->uncompressed.bDefaultFrameIndex; + break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: + frmnum = fmt->mjpeg.bDefaultFrameIndex; + break; + default: return false; + } break; default: return false; } param->bFrameIndex = (uint8_t)frmnum; /* Set the parameters determined by the frame */ - tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - param->dwMaxVideoFrameSize = (uint32_t)(frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8); + tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); + uint_fast32_t frame_size; + switch (fmt->bDescriptorSubType) { + case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: + frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->uncompressed.bBitsPerPixel / 8; + break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: + frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ + break; + default: return false; + } + param->dwMaxVideoFrameSize = frame_size; return true; } @@ -491,17 +512,17 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); TU_ASSERT(vs); void const *end = _end_of_streaming_descriptor(vs); - tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); - tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); + tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); + tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); uint_fast32_t interval, interval_ms; switch (request) { case VIDEO_REQUEST_GET_MAX: { uint_fast32_t min_interval, max_interval; - uint_fast8_t num_intervals = frm->bFrameIntervalType; - max_interval = num_intervals ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[1]; - min_interval = frm->dwFrameInterval[0]; + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; + max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; + min_interval = frm->uncompressed.dwFrameInterval[0]; interval = max_interval; interval_ms = min_interval / 10000; } @@ -509,24 +530,24 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * case VIDEO_REQUEST_GET_MIN: { uint_fast32_t min_interval, max_interval; - uint_fast8_t num_intervals = frm->bFrameIntervalType; - max_interval = num_intervals ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[1]; - min_interval = frm->dwFrameInterval[0]; + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; + max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; + min_interval = frm->uncompressed.dwFrameInterval[0]; interval = min_interval; interval_ms = max_interval / 10000; } break; case VIDEO_REQUEST_GET_DEF: - interval = frm->dwDefaultFrameInterval; + interval = frm->uncompressed.dwDefaultFrameInterval; interval_ms = interval / 10000; break; case VIDEO_REQUEST_GET_RES: { - uint_fast8_t num_intervals = frm->bFrameIntervalType; + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; if (num_intervals) { interval = 0; } else { - interval = frm->dwFrameInterval[2]; + interval = frm->uncompressed.dwFrameInterval[2]; interval_ms = interval / 10000; } } -- cgit v1.3.1 From 4ec1643bdbca34d0e6d575646ed556087bac5d6e Mon Sep 17 00:00:00 2001 From: Mark K Cowan Date: Thu, 20 Oct 2022 22:45:58 +0300 Subject: do not apply storage attributes to member of struct --- src/class/audio/audio_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a021755ba..0eccf282d 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -341,7 +341,7 @@ typedef struct // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; + uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; #endif // Decoding parameters - parameters are set when alternate AS interface is set by host -- cgit v1.3.1 From 815c2cc9959cc9a127d4ff64f65743d4ac8713ce Mon Sep 17 00:00:00 2001 From: Mark K Cowan Date: Mon, 24 Oct 2022 20:36:45 +0300 Subject: keep alignment spec --- src/class/audio/audio_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 0eccf282d..2b22834b6 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -341,7 +341,7 @@ typedef struct // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; + CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; #endif // Decoding parameters - parameters are set when alternate AS interface is set by host -- cgit v1.3.1