summaryrefslogtreecommitdiff
path: root/src/class
diff options
context:
space:
mode:
Diffstat (limited to 'src/class')
-rw-r--r--src/class/audio/audio_device.c147
-rw-r--r--src/class/audio/audio_device.h60
2 files changed, 179 insertions, 28 deletions
diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c
index 2660cf368..181703f75 100644
--- a/src/class/audio/audio_device.c
+++ b/src/class/audio/audio_device.c
@@ -46,6 +46,19 @@
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
+
+#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
+#ifndef CFG_TUD_AUDIO_TX_FIFO_COUNT
+#define CFG_TUD_AUDIO_TX_FIFO_COUNT CFG_TUD_AUDIO_N_CHANNELS_TX
+#endif
+#endif
+
+#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE
+#ifndef CFG_TUD_AUDIO_RX_FIFO_COUNT
+#define CFG_TUD_AUDIO_RX_FIFO_COUNT CFG_TUD_AUDIO_N_CHANNELS_RX
+#endif
+#endif
+
typedef struct
{
uint8_t rhport;
@@ -81,18 +94,18 @@ typedef struct
// FIFO
#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
- tu_fifo_t tx_ff[CFG_TUD_AUDIO_N_CHANNELS_TX];
- CFG_TUSB_MEM_ALIGN uint8_t tx_ff_buf[CFG_TUD_AUDIO_N_CHANNELS_TX][CFG_TUD_AUDIO_TX_FIFO_SIZE * CFG_TUD_AUDIO_TX_ITEMSIZE];
+ tu_fifo_t tx_ff[CFG_TUD_AUDIO_TX_FIFO_COUNT];
+ CFG_TUSB_MEM_ALIGN uint8_t tx_ff_buf[CFG_TUD_AUDIO_TX_FIFO_COUNT][CFG_TUD_AUDIO_TX_FIFO_SIZE];
#if CFG_FIFO_MUTEX
- osal_mutex_def_t tx_ff_mutex[CFG_TUD_AUDIO_N_CHANNELS_TX];
+ osal_mutex_def_t tx_ff_mutex[CFG_TUD_AUDIO_TX_FIFO_COUNT];
#endif
#endif
#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE
- tu_fifo_t rx_ff[CFG_TUD_AUDIO_N_CHANNELS_RX];
- CFG_TUSB_MEM_ALIGN uint8_t rx_ff_buf[CFG_TUD_AUDIO_N_CHANNELS_RX][CFG_TUD_AUDIO_RX_FIFO_SIZE * CFG_TUD_AUDIO_RX_ITEMSIZE];
+ tu_fifo_t rx_ff[CFG_TUD_AUDIO_RX_FIFO_COUNT];
+ CFG_TUSB_MEM_ALIGN uint8_t rx_ff_buf[CFG_TUD_AUDIO_RX_FIFO_COUNT][CFG_TUD_AUDIO_RX_FIFO_SIZE];
#if CFG_FIFO_MUTEX
- osal_mutex_def_t rx_ff_mutex[CFG_TUD_AUDIO_N_CHANNELS_RX];
+ osal_mutex_def_t rx_ff_mutex[CFG_TUD_AUDIO_RX_FIFO_COUNT];
#endif
#endif
@@ -190,7 +203,7 @@ bool tud_audio_n_mounted(uint8_t itf)
//--------------------------------------------------------------------+
#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE
-
+#if CFG_TUD_AUDIO_RX_FIFO_COUNT > 1
uint16_t tud_audio_n_available(uint8_t itf, uint8_t channelId)
{
TU_VERIFY(channelId < CFG_TUD_AUDIO_N_CHANNELS_RX);
@@ -208,7 +221,22 @@ void tud_audio_n_read_flush (uint8_t itf, uint8_t channelId)
TU_VERIFY(channelId < CFG_TUD_AUDIO_N_CHANNELS_RX, );
tu_fifo_clear(&_audiod_itf[itf].rx_ff[channelId]);
}
+#else
+uint16_t tud_audio_n_available(uint8_t itf)
+{
+ return tu_fifo_count(&_audiod_itf[itf].rx_ff[0]);
+}
+uint16_t tud_audio_n_read(uint8_t itf, void* buffer, uint16_t bufsize)
+{
+ return tu_fifo_read_n(&_audiod_itf[itf].rx_ff[0], buffer, bufsize);
+}
+
+void tud_audio_n_read_flush (uint8_t itf)
+{
+ tu_fifo_clear(&_audiod_itf[itf].rx_ff[0]);
+}
+#endif
#endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
@@ -283,6 +311,7 @@ static bool audio_rx_done_cb(uint8_t rhport, audiod_interface_t* audio, uint8_t*
// The following functions are used in case CFG_TUD_AUDIO_RX_FIFO_SIZE != 0
#if CFG_TUD_AUDIO_RX_FIFO_SIZE
+#if CFG_TUD_AUDIO_RX_FIFO_COUNT > 1
static bool audio_rx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t* audio, uint8_t * buffer, uint16_t bufsize)
{
(void) rhport;
@@ -318,7 +347,23 @@ static bool audio_rx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t* a
chId = 0;
}
}
-} }
+ return true;
+}
+#else
+static bool audio_rx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t *audio, uint8_t *buffer, uint16_t bufsize)
+{
+ (void) rhport;
+
+ // We expect to get a multiple of CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX per channel
+ if (bufsize % (CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX) != 0)
+ {
+ return false;
+ }
+
+ tu_fifo_write_n(&audio->rx_ff[0], buffer, bufsize);
+ return true;
+}
+#endif // CFG_TUD_AUDIO_RX_FIFO_COUNT > 1
#endif //CFG_TUD_AUDIO_RX_FIFO_SIZE
//--------------------------------------------------------------------+
@@ -336,9 +381,9 @@ static bool audio_rx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t* a
* \param[in] len: # of array elements to copy
* \return Number of bytes actually written
*/
-
+#if CFG_TUD_AUDIO_EPSIZE_IN
+#if !CFG_TUD_AUDIO_TX_FIFO_SIZE
/* This function is intended for later use once EP buffers (at least for ISO EPs) are implemented as ring buffers
-#if CFG_TUD_AUDIO_EPSIZE_IN && !CFG_TUD_AUDIO_TX_FIFO_SIZE
uint16_t tud_audio_n_write_ep_in_buffer(uint8_t itf, const void * data, uint16_t len)
{
audiod_interface_t* audio = &_audiod_itf[itf];
@@ -365,11 +410,23 @@ uint16_t tud_audio_n_write_ep_in_buffer(uint8_t itf, const void * data, uint16_t
// Return number of bytes written
return len;
}
-#endif
-
*/
-#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
+#else
+
+#if CFG_TUD_AUDIO_TX_FIFO_COUNT == 1
+uint16_t tud_audio_n_write(uint8_t itf, void const* data, uint16_t len)
+{
+ {
+ audiod_interface_t* audio = &_audiod_itf[itf];
+ if (audio->p_desc == NULL)
+ {
+ return 0;
+ }
+ return tu_fifo_write_n(&audio->tx_ff[0], data, len);
+ }
+}
+#else
uint16_t tud_audio_n_write(uint8_t itf, uint8_t channelId, const void * data, uint16_t len)
{
audiod_interface_t* audio = &_audiod_itf[itf];
@@ -381,6 +438,23 @@ uint16_t tud_audio_n_write(uint8_t itf, uint8_t channelId, const void * data, ui
}
#endif
+static bool audiod_tx_done_cb(uint8_t rhport, audiod_interface_t* audio, uint16_t * n_bytes_copied);
+
+uint16_t tud_audio_n_write_flush(uint8_t itf)
+{
+ audiod_interface_t *audio = &_audiod_itf[itf];
+ if (audio->p_desc == NULL) {
+ return 0;
+ }
+
+ uint16_t n_bytes_copied;
+ TU_VERIFY(audiod_tx_done_cb(audio->rhport, audio, &n_bytes_copied));
+ return n_bytes_copied;
+}
+
+#endif
+#endif
+
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0
uint32_t tud_audio_int_ctr_n_write(uint8_t itf, uint8_t const* buffer, uint32_t bufsize)
{
@@ -477,6 +551,7 @@ static bool audiod_tx_done_cb(uint8_t rhport, audiod_interface_t* audio, uint16_
#endif //CFG_TUD_AUDIO_EPSIZE_IN
#if CFG_TUD_AUDIO_TX_FIFO_SIZE
+#if CFG_TUD_AUDIO_TX_FIFO_COUNT > 1 || (CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX != CFG_TUD_AUDIO_TX_ITEMSIZE)
static bool audiod_tx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t* audio)
{
// We encode directly into IN EP's buffer - abort if previous transfer not complete
@@ -484,15 +559,15 @@ static bool audiod_tx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t*
// Determine amount of samples
uint16_t const nEndpointSampleCapacity = CFG_TUD_AUDIO_EPSIZE_IN / CFG_TUD_AUDIO_N_CHANNELS_TX / CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX;
- uint16_t nSamplesPerChannelToSend = tu_fifo_count(&audio->tx_ff[0]);
+ uint16_t nSamplesPerChannelToSend = tu_fifo_count(&audio->tx_ff[0]) / CFG_TUD_AUDIO_TX_ITEMSIZE;
uint16_t nBytesToSend;
uint8_t cntChannel;
for (cntChannel = 1; cntChannel < CFG_TUD_AUDIO_N_CHANNELS_TX; cntChannel++)
{
- if (audio->tx_ff[cntChannel].count < nSamplesPerChannelToSend)
+ if (audio->tx_ff[cntChannel].count / CFG_TUD_AUDIO_TX_ITEMSIZE < nSamplesPerChannelToSend)
{
- nSamplesPerChannelToSend = audio->tx_ff[cntChannel].count;
+ nSamplesPerChannelToSend = audio->tx_ff[cntChannel].count * CFG_TUD_AUDIO_TX_ITEMSIZE;
}
}
@@ -524,7 +599,7 @@ static bool audiod_tx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t*
for (cntChannel = 0; cntChannel < CFG_TUD_AUDIO_N_CHANNELS_TX; cntChannel++)
{
// Get sample from buffer
- tu_fifo_read(&audio->tx_ff[cntChannel], &sample);
+ tu_fifo_read_n(&audio->tx_ff[cntChannel], &sample, CFG_TUD_AUDIO_TX_ITEMSIZE);
// Put it into EP's buffer - Let alignment problems be handled by memcpy
memcpy(pBuff, &sample, CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX);
@@ -539,6 +614,30 @@ static bool audiod_tx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t*
return true;
}
+#else
+static bool audiod_tx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t* audio)
+{
+ // We encode directly into IN EP's buffer - abort if previous transfer not complete
+ TU_VERIFY(!usbd_edpt_busy(rhport, audio->ep_in));
+
+ // Determine amount of samples
+ uint16_t nByteCount = tu_fifo_count(&audio->tx_ff[0]);
+
+ nByteCount = tu_min16(nByteCount, CFG_TUD_AUDIO_EPSIZE_IN);
+
+ // Check if there is enough
+ if (nByteCount == 0)
+ {
+ return true;
+ }
+
+ nByteCount = tu_fifo_read_n(&audio->tx_ff[0], audio->epin_buf, nByteCount);
+ audio->epin_buf_cnt = nByteCount;
+
+ return true;
+}
+#endif // CFG_TUD_AUDIO_TX_FIFO_COUNT > 1 || (CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX != CFG_TUD_AUDIO_TX_ITEMSIZE)
+
#endif //CFG_TUD_AUDIO_TX_FIFO_SIZE
// This function is called once a transmit of an feedback packet was successfully completed. Here, we get the next feedback value to be sent
@@ -588,7 +687,6 @@ static bool audio_int_ctr_done_cb(uint8_t rhport, audiod_interface_t* audio, uin
//--------------------------------------------------------------------+
void audiod_init(void)
{
- uint8_t cnt;
tu_memclr(_audiod_itf, sizeof(_audiod_itf));
for(uint8_t i=0; i<CFG_TUD_AUDIO; i++)
@@ -597,9 +695,9 @@ void audiod_init(void)
// Initialize TX FIFOs if required
#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
- for (cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_TX; cnt++)
+ for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_TX_FIFO_COUNT; cnt++)
{
- tu_fifo_config(&audio->tx_ff[cnt], &audio->tx_ff_buf[cnt], CFG_TUD_AUDIO_TX_FIFO_SIZE, CFG_TUD_AUDIO_TX_ITEMSIZE, true);
+ tu_fifo_config(&audio->tx_ff[cnt], &audio->tx_ff_buf[cnt], CFG_TUD_AUDIO_TX_FIFO_SIZE, 1, true);
#if CFG_FIFO_MUTEX
tu_fifo_config_mutex(&audio->tx_ff[cnt], osal_mutex_create(&audio->tx_ff_mutex[cnt]));
#endif
@@ -607,9 +705,9 @@ void audiod_init(void)
#endif
#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE
- for (cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_RX; cnt++)
+ for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_RX_FIFO_COUNT; cnt++)
{
- tu_fifo_config(&audio->rx_ff[cnt], &audio->rx_ff_buf[cnt], CFG_TUD_AUDIO_RX_FIFO_SIZE, CFG_TUD_AUDIO_RX_ITEMSIZE, true);
+ tu_fifo_config(&audio->rx_ff[cnt], &audio->rx_ff_buf[cnt], CFG_TUD_AUDIO_RX_FIFO_SIZE, 1, true);
#if CFG_FIFO_MUTEX
tu_fifo_config_mutex(&audio->rx_ff[cnt], osal_mutex_create(&audio->rx_ff_mutex[cnt]));
#endif
@@ -634,16 +732,15 @@ void audiod_reset(uint8_t rhport)
audiod_interface_t* audio = &_audiod_itf[i];
tu_memclr(audio, ITF_MEM_RESET_SIZE);
- uint8_t cnt;
#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
- for (cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_TX; cnt++)
+ for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_TX_FIFO_COUNT; cnt++)
{
tu_fifo_clear(&audio->tx_ff[cnt]);
}
#endif
#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE
- for (cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_RX; cnt++)
+ for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_RX_FIFO_COUNT; cnt++)
{
tu_fifo_clear(&audio->rx_ff[cnt]);
}
diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h
index 2adb95252..2f48955f2 100644
--- a/src/class/audio/audio_device.h
+++ b/src/class/audio/audio_device.h
@@ -119,6 +119,7 @@
#define CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX 1
#endif
+#ifndef CFG_TUD_AUDIO_TX_ITEMSIZE
#if CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX == 1
#define CFG_TUD_AUDIO_TX_ITEMSIZE 1
#elif CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX == 2
@@ -126,6 +127,11 @@
#else
#define CFG_TUD_AUDIO_TX_ITEMSIZE 4
#endif
+#endif
+
+#if CFG_TUD_AUDIO_TX_ITEMSIZE < CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX
+#error FIFO element size (ITEMSIZE) must not be smaller then sample size
+#endif
#endif
@@ -170,9 +176,15 @@ extern "C" {
bool tud_audio_n_mounted (uint8_t itf);
#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE
+#if CFG_TUD_AUDIO_RX_FIFO_COUNT > 1
uint16_t tud_audio_n_available (uint8_t itf, uint8_t channelId);
uint16_t tud_audio_n_read (uint8_t itf, uint8_t channelId, void* buffer, uint16_t bufsize);
void tud_audio_n_read_flush (uint8_t itf, uint8_t channelId);
+#else
+uint16_t tud_audio_n_available (uint8_t itf);
+uint16_t tud_audio_n_read (uint8_t itf, void* buffer, uint16_t bufsize);
+void tud_audio_n_read_flush (uint8_t itf);
+#endif
#endif
/* This function is intended for later use once EP buffers (at least for ISO EPs) are implemented as ring buffers
@@ -182,7 +194,12 @@ uint16_t tud_audio_n_write_ep_in_buffer(uint8_t itf, const void * data, uint16_t
*/
#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
+#if CFG_TUD_AUDIO_TX_FIFO_COUNT > 1
uint16_t tud_audio_n_write (uint8_t itf, uint8_t channelId, const void * data, uint16_t len);
+#else
+uint16_t tud_audio_n_write (uint8_t itf, const void * data, uint16_t len);
+#endif
+uint16_t tud_audio_n_write_flush(uint8_t itf);
#endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0
@@ -205,7 +222,11 @@ static inline void tud_audio_read_flush (void);
#endif
#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
+#if CFG_TUD_AUDIO_TX_FIFO_COUNT > 1
static inline uint16_t tud_audio_write (uint8_t channelId, uint8_t const* buffer, uint16_t bufsize);
+#else
+static inline uint16_t tud_audio_write (uint8_t const* buffer, uint16_t bufsize);
+#endif
#endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0
@@ -274,14 +295,31 @@ static inline bool tud_audio_mounted(void)
return tud_audio_n_mounted(0);
}
-#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
-static inline uint16_t tud_audio_write (uint8_t channelId, uint8_t const* buffer, uint16_t bufsize) // Short version if only one audio function is used
+#if CFG_TUD_AUDIO_EPSIZE_IN
+#if CFG_TUD_AUDIO_TX_FIFO_SIZE && CFG_TUD_AUDIO_TX_FIFO_COUNT > 1
+static inline uint16_t tud_audio_write (uint8_t channelId, uint8_t const* buffer, uint16_t n_bytes) // Short version if only one audio function is used
+{
+ return tud_audio_n_write(0, channelId, buffer, n_bytes);
+}
+#else
+static inline uint16_t tud_audio_write (uint8_t const* buffer, uint16_t n_bytes) // Short version if only one audio function is used
+{
+ return tud_audio_n_write(0, buffer, n_bytes);
+}
+#endif
+
+static inline uint16_t tud_audio_write_flush (void) // Short version if only one audio function is used
{
- return tud_audio_n_write(0, channelId, buffer, bufsize);
+#if CFG_TUD_AUDIO_TX_FIFO_SIZE
+ return tud_audio_n_write_flush(0);
+#else
+ return 0;
+#endif
}
#endif // CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE
+#if CFG_TUD_AUDIO_RX_FIFO_COUNT > 1
static inline uint16_t tud_audio_available(uint8_t channelId)
{
return tud_audio_n_available(0, channelId);
@@ -296,6 +334,22 @@ static inline void tud_audio_read_flush(uint8_t channelId)
{
tud_audio_n_read_flush(0, channelId);
}
+#else
+static inline uint16_t tud_audio_available(void)
+{
+ return tud_audio_n_available(0);
+}
+
+static inline uint16_t tud_audio_read(void *buffer, uint16_t bufsize)
+{
+ return tud_audio_n_read(0, buffer, bufsize);
+}
+
+static inline void tud_audio_read_flush(void)
+{
+ tud_audio_n_read_flush(0);
+}
+#endif
#endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0