Skip to content

Commit 8e7c7a5

Browse files
authored
Merge pull request #173 from adafruit/update-tinyusb
Update tinyusb
2 parents 366da4d + 244c3a4 commit 8e7c7a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+4895
-370
lines changed

.github/workflows/githubci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ jobs:
4141
- name: pre-install
4242
run: bash ci/actions_install.sh
4343

44+
#- name: Install Libraries for building examples
45+
# run: arduino-cli lib install "Adafruit SPIFlash" "MIDI Library" "Adafruit seesaw Library" "Adafruit NeoPixel" "SdFat - Adafruit Fork" "SD" "Adafruit Circuit Playground" "Adafruit InternalFlash"
46+
4447
- name: test platforms
4548
run: python3 ci/build_platform.py ${{ matrix.arduino-platform }}
4649

examples/CDC/cdc_multi/cdc_multi.ino

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
/*
22
This example demonstrates the use of multiple USB CDC/ACM "Virtual
3-
Serial" ports, using Ha Thach's TinyUSB library, and the port of
4-
that library to the Arduino environment
5-
6-
https://github.com/hathach/tinyusb
7-
https://github.com/adafruit/Adafruit_TinyUSB_Arduino
3+
Serial" ports
84
95
Written by Bill Westfield (aka WestfW), June 2021.
106
Copyright 2021 by Bill Westfield
117
MIT license, check LICENSE for more information
8+
*/
129

13-
The example creates three virtual serial ports. Text entered on
14-
any of the ports will be echoed to the all ports.
10+
/* The example creates two virtual serial ports. Text entered on
11+
any of the ports will be echoed to the all ports with
12+
- all lower case in port0 (Serial)
13+
- all upper case in port1
1514
16-
The max number of CDC ports (CFG_TUD_CDC) has to be changed to at
17-
least 2, changed in the core tusb_config.h file.
15+
The max number of CDC ports (CFG_TUD_CDC) has to be changed to at least 2.
16+
Config file is located in Adafruit_TinyUSB_Arduino/src/arduino/ports/platform/tusb_config_platform.h
17+
where platform is one of: esp32, nrf, rp2040, samd
1818
*/
1919

2020
#include <Adafruit_TinyUSB.h>

src/class/audio/audio_device.c

Lines changed: 220 additions & 45 deletions
Large diffs are not rendered by default.

src/class/audio/audio_device.h

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,14 @@ TU_ATTR_WEAK bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_byte
458458
#endif
459459

460460
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
461-
TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport);
461+
TU_ATTR_WEAK void tud_audio_fb_done_cb(uint8_t func_id);
462+
463+
464+
// 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.
465+
466+
// 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).
467+
468+
// 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().
462469

463470
// 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.
464471
//
@@ -468,9 +475,61 @@ TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport);
468475
//
469476
// 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
470477
// driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format.
478+
479+
// 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.
480+
481+
// Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec
482+
// Boiled down, the feedback value Ff = n_samples / (micro)frame.
483+
// 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)
484+
// 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)
485+
// 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
486+
471487
bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback);
472488
static inline bool tud_audio_fb_set(uint32_t feedback);
489+
490+
// Update feedback value with passed cycles since last time this update function is called.
491+
// Typically called within tud_audio_sof_isr(). Required tud_audio_feedback_params_cb() is implemented
492+
// This function will also call tud_audio_feedback_set()
493+
// return feedback value in 16.16 for reference (0 for error)
494+
uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles);
495+
496+
enum {
497+
AUDIO_FEEDBACK_METHOD_DISABLED,
498+
AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED,
499+
AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT,
500+
AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2,
501+
502+
// impelemnt later
503+
// AUDIO_FEEDBACK_METHOD_FIFO_COUNT
504+
};
505+
506+
typedef struct {
507+
uint8_t method;
508+
uint32_t sample_freq; // sample frequency in Hz
509+
510+
union {
511+
struct {
512+
uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on
513+
}frequency;
514+
515+
#if 0 // implement later
516+
struct {
517+
uint32_t threshold_bytes; // minimum number of bytes received to be considered as filled/ready
518+
}fifo_count;
473519
#endif
520+
};
521+
}audio_feedback_params_t;
522+
523+
// Invoked when needed to set feedback parameters
524+
TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param);
525+
526+
// Callback in ISR context, invoked periodically according to feedback endpoint bInterval.
527+
// Could be used to compute and update feedback value, should be placed in RAM if possible
528+
// frame_number : current SOF count
529+
// interval_shift: number of bit shift i.e log2(interval) from Feedback endpoint descriptor
530+
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);
531+
532+
#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
474533

475534
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
476535
TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied);
@@ -612,10 +671,12 @@ static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t l
612671
#endif
613672

614673
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
674+
615675
static inline bool tud_audio_fb_set(uint32_t feedback)
616676
{
617677
return tud_audio_n_fb_set(0, feedback);
618678
}
679+
619680
#endif
620681

621682
//--------------------------------------------------------------------+
@@ -626,6 +687,7 @@ void audiod_reset (uint8_t rhport);
626687
uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
627688
bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
628689
bool audiod_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
690+
void audiod_sof_isr (uint8_t rhport, uint32_t frame_count);
629691

630692
#ifdef __cplusplus
631693
}

src/class/bth/bth_device.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,12 @@ CFG_TUSB_MEM_SECTION btd_interface_t _btd_itf;
5959

6060
static bool bt_tx_data(uint8_t ep, void *data, uint16_t len)
6161
{
62+
uint8_t const rhport = 0;
63+
6264
// skip if previous transfer not complete
63-
TU_VERIFY(!usbd_edpt_busy(TUD_OPT_RHPORT, ep));
65+
TU_VERIFY(!usbd_edpt_busy(rhport, ep));
6466

65-
TU_ASSERT(usbd_edpt_xfer(TUD_OPT_RHPORT, ep, data, len));
67+
TU_ASSERT(usbd_edpt_xfer(rhport, ep, data, len));
6668

6769
return true;
6870
}

src/class/cdc/cdc_device.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
8282

8383
static bool _prep_out_transaction (cdcd_interface_t* p_cdc)
8484
{
85-
uint8_t const rhport = TUD_OPT_RHPORT;
85+
uint8_t const rhport = 0;
8686
uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff);
8787

8888
// 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)
189189
// No data to send
190190
if ( !tu_fifo_count(&p_cdc->tx_ff) ) return 0;
191191

192-
uint8_t const rhport = TUD_OPT_RHPORT;
192+
uint8_t const rhport = 0;
193193

194194
// Claim the endpoint
195195
TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 );

src/class/hid/hid_device.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,9 @@ static inline uint8_t get_index_by_itfnum(uint8_t itf_num)
7676
//--------------------------------------------------------------------+
7777
bool tud_hid_n_ready(uint8_t instance)
7878
{
79+
uint8_t const rhport = 0;
7980
uint8_t const ep_in = _hidd_itf[instance].ep_in;
80-
return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(TUD_OPT_RHPORT, ep_in);
81+
return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in);
8182
}
8283

8384
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
103104
memcpy(p_hid->epin_buf, report, len);
104105
}
105106

106-
return usbd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->epin_buf, len);
107+
return usbd_edpt_xfer(rhport, p_hid->ep_in, p_hid->epin_buf, len);
107108
}
108109

109110
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,
172173
//--------------------------------------------------------------------+
173174
void hidd_init(void)
174175
{
175-
hidd_reset(TUD_OPT_RHPORT);
176+
hidd_reset(0);
176177
}
177178

178179
void hidd_reset(uint8_t rhport)

0 commit comments

Comments
 (0)