Generalize audio driver for 3 audio functions plus a lot more.
- Audio format and parameters are parsed from descriptors thus user no longer needs to give them explicitely - Tested for 4 channel software type I PCM encoding with 16 bit with 1 channel per FIFO and 2 channels per FIFO (this is I2S specific)
This commit is contained in:
@@ -53,17 +53,17 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||
|
||||
// Audio controls
|
||||
// Current states
|
||||
bool mute[CFG_TUD_AUDIO_N_CHANNELS_TX + 1]; // +1 for master channel 0
|
||||
uint16_t volume[CFG_TUD_AUDIO_N_CHANNELS_TX + 1]; // +1 for master channel 0
|
||||
bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
|
||||
uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
|
||||
uint32_t sampFreq;
|
||||
uint8_t clkValid;
|
||||
|
||||
// Range states
|
||||
audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_N_CHANNELS_TX+1]; // Volume range state
|
||||
audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state
|
||||
audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
|
||||
|
||||
// Audio test data
|
||||
uint16_t test_buffer_audio[CFG_TUD_AUDIO_EPSIZE_IN/2];
|
||||
uint16_t test_buffer_audio[CFG_TUD_AUDIO_EP_SZ_IN/2];
|
||||
uint16_t startVal = 0;
|
||||
|
||||
void led_blinking_task(void);
|
||||
|
@@ -91,6 +91,21 @@ extern "C" {
|
||||
// AUDIO CLASS DRIVER CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// Have a look into audio_device.h for all configurations
|
||||
|
||||
#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN
|
||||
#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes)
|
||||
#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 // Size of control request buffer
|
||||
|
||||
#define CFG_TUD_AUDIO_ENABLE_EP_IN 1
|
||||
#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below
|
||||
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor!
|
||||
#define CFG_TUD_AUDIO_EP_SZ_IN 48 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x 1 Channel
|
||||
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
|
||||
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN + 1
|
||||
|
||||
|
||||
|
||||
// Audio format type
|
||||
#define CFG_TUD_AUDIO_FORMAT_TYPE_TX AUDIO_FORMAT_TYPE_I
|
||||
|
||||
@@ -100,14 +115,11 @@ extern "C" {
|
||||
#define CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX 2
|
||||
|
||||
// EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense)
|
||||
#define CFG_TUD_AUDIO_ENABLE_EP_IN 1
|
||||
#define CFG_TUD_AUDIO_EPSIZE_IN 48 * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_N_CHANNELS_TX // ceil(f_s/1000) * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_N_CHANNELS_TX
|
||||
#define CFG_TUD_AUDIO_EP_IN_SW_BUFFER_SIZE CFG_TUD_AUDIO_EPSIZE_IN + CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_N_CHANNELS_TX // Just for safety one sample more space
|
||||
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EPSIZE_IN + CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_N_CHANNELS_TX // Just for safety one sample more space
|
||||
|
||||
// Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes)
|
||||
#define CFG_TUD_AUDIO_N_AS_INT 1
|
||||
|
||||
// Size of control request buffer
|
||||
#define CFG_TUD_AUDIO_CTRL_BUF_SIZE 64
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ enum
|
||||
ITF_NUM_TOTAL
|
||||
};
|
||||
|
||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_DESC_LEN)
|
||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_ONE_CH_DESC_LEN)
|
||||
|
||||
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
|
||||
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
|
||||
@@ -89,20 +89,13 @@ enum
|
||||
#define EPNUM_AUDIO 0x01
|
||||
#endif
|
||||
|
||||
// These variables are required by the audio driver in audio_device.c
|
||||
|
||||
// List of audio descriptor lengths which is required by audio driver - you need as many entries as CFG_TUD_AUDIO - unfortunately this is not possible to determine otherwise
|
||||
const uint16_t tud_audio_desc_lengths[] = {TUD_AUDIO_MIC_DESC_LEN};
|
||||
|
||||
// TAKE CARE - THE NUMBER OF AUDIO STREAMING INTERFACES PER AUDIO FUNCTION MUST NOT EXCEED CFG_TUD_AUDIO_N_AS_INT - IF IT DOES INCREASE CFG_TUD_AUDIO_N_AS_INT IN tusb_config.h!
|
||||
|
||||
uint8_t const desc_configuration[] =
|
||||
{
|
||||
// Interface count, string index, total length, attribute, power in mA
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
|
||||
// Interface number, string index, EP Out & EP In address, EP size
|
||||
TUD_AUDIO_MIC_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ 16, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EPSIZE_IN)
|
||||
TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN)
|
||||
};
|
||||
|
||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||
|
@@ -91,35 +91,31 @@ extern "C" {
|
||||
//--------------------------------------------------------------------
|
||||
// AUDIO CLASS DRIVER CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
#define CFG_TUD_AUDIO_IN_PATH (CFG_TUD_AUDIO)
|
||||
#define CFG_TUD_AUDIO_OUT_PATH (CFG_TUD_AUDIO)
|
||||
|
||||
// Audio format type
|
||||
#define CFG_TUD_AUDIO_FORMAT_TYPE_TX AUDIO_FORMAT_TYPE_I
|
||||
#define CFG_TUD_AUDIO_FORMAT_TYPE_RX AUDIO_FORMAT_TYPE_I
|
||||
#define CFG_TUD_AUDIO_IN_PATH (CFG_TUD_AUDIO)
|
||||
#define CFG_TUD_AUDIO_OUT_PATH (CFG_TUD_AUDIO)
|
||||
|
||||
// Audio format type I specifications
|
||||
#define CFG_TUD_AUDIO_FORMAT_TYPE_I_TX AUDIO_DATA_FORMAT_TYPE_I_PCM
|
||||
#define CFG_TUD_AUDIO_FORMAT_TYPE_I_RX AUDIO_DATA_FORMAT_TYPE_I_PCM
|
||||
#define CFG_TUD_AUDIO_N_CHANNELS_TX 1
|
||||
#define CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX 2
|
||||
#define CFG_TUD_AUDIO_N_CHANNELS_RX 2
|
||||
#define CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX 2
|
||||
#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0
|
||||
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1
|
||||
#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2
|
||||
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2
|
||||
#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX 2
|
||||
#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0
|
||||
|
||||
// EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense)
|
||||
#define CFG_TUD_AUDIO_EPSIZE_IN (CFG_TUD_AUDIO_IN_PATH * (48 + 1) * (CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX) * (CFG_TUD_AUDIO_N_CHANNELS_TX)) // 48 Samples (48 kHz) x 2 Bytes/Sample x n Channels
|
||||
#define CFG_TUD_AUDIO_EP_IN_SW_BUFFER_SIZE CFG_TUD_AUDIO_EPSIZE_IN
|
||||
#define CFG_TUD_AUDIO_ENABLE_EP_IN 1
|
||||
#define CFG_TUD_AUDIO_EP_SZ_IN (CFG_TUD_AUDIO_IN_PATH * (48 + 1) * (CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX) * (CFG_TUD_AUDIO_N_CHANNELS_TX)) // 48 Samples (48 kHz) x 2 Bytes/Sample x n Channels
|
||||
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EPSIZE_IN
|
||||
|
||||
// EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense)
|
||||
#define CFG_TUD_AUDIO_EPSIZE_OUT (CFG_TUD_AUDIO_OUT_PATH * ((48 + CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP) * (CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX) * (CFG_TUD_AUDIO_N_CHANNELS_RX))) // N Samples (N kHz) x 2 Bytes/Sample x n Channels
|
||||
#define CFG_TUD_AUDIO_EP_OUT_SW_BUFFER_SIZE CFG_TUD_AUDIO_EPSIZE_OUT*3
|
||||
#define CFG_TUD_AUDIO_ENABLE_EP_OUT 1
|
||||
#define CFG_TUD_AUDIO_EP_OUT_SZ (CFG_TUD_AUDIO_OUT_PATH * ((48 + CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP) * (CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX) * (CFG_TUD_AUDIO_N_CHANNELS_RX))) // N Samples (N kHz) x 2 Bytes/Sample x n Channels
|
||||
#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ CFG_TUD_AUDIO_EP_OUT_SZ*3
|
||||
|
||||
// Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes)
|
||||
#define CFG_TUD_AUDIO_N_AS_INT 1
|
||||
#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1
|
||||
|
||||
// Size of control request buffer
|
||||
#define CFG_TUD_AUDIO_CTRL_BUF_SIZE 64
|
||||
#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -98,7 +98,7 @@ uint8_t const desc_configuration[] =
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
|
||||
// Interface number, string index, EP Out & EP In address, EP size
|
||||
TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, 2, 16, EPNUM_AUDIO, CFG_TUD_AUDIO_EPSIZE_OUT, EPNUM_AUDIO | 0x80, CFG_TUD_AUDIO_EPSIZE_IN)
|
||||
TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, 2, 16, EPNUM_AUDIO, CFG_TUD_AUDIO_EP_OUT_SZ, EPNUM_AUDIO | 0x80, CFG_TUD_AUDIO_EP_SZ_IN)
|
||||
};
|
||||
|
||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||
|
Reference in New Issue
Block a user