Opts for fitting beclear

This commit is contained in:
Ross Owen
2016-12-05 19:26:14 +00:00
parent 9c5bff58c4
commit ca1925db7a
15 changed files with 224 additions and 121 deletions

View File

@@ -31,11 +31,30 @@
#include "commands.h"
#include "xc_ptr.h"
/* TODO 32 is max expected channels */
static unsigned samplesOut[32];
#define MAX(x,y) ((x)>(y) ? (x) : (y))
/* Two buffers for ADC data to allow for DAC and ADC ports being offset */
static unsigned samplesIn[2][32];
static unsigned samplesOut[MAX(NUM_USB_CHAN_OUT, I2S_CHANS_DAC)];
#ifndef ADAT_RX
#define ADAT_RX 0
#endif
#ifndef SPDIF_RX
#define SPDIF_RX 0
#endif
/* Two buffers for ADC data to allow for DAC and ADC I2S ports being offset */
#define IN_CHAN_COUNT (I2S_CHANS_ADC + NUM_PDM_MICS + (8*ADAT_RX) + (2*SPDIF_RX))
static unsigned samplesIn[2][MAX(NUM_USB_CHAN_IN, IN_CHAN_COUNT)];
#if defined(ADAT_RX) && (ADAT_RX ==0)
#undef ADAT_RX
#endif
#if defined(SPDIF_RX) && (SPDIF_RX ==0)
#undef SPDIF_RX
#endif
#if (DSD_CHANS_DAC != 0)
extern buffered out port:32 p_dsd_dac[DSD_CHANS_DAC];
@@ -1155,10 +1174,7 @@ chanend ?c_config, chanend ?c
#if (NUM_PDM_MICS > 0)
c_pdm_in,
#endif
null
//#ifdef RUN_DSP_TASK
, i_audMan
//#endif
null, i_audMan
);
if(command == SET_SAMPLE_FREQ)

View File

@@ -1218,7 +1218,11 @@ enum USBEndpointNumber_Out
#define DFU_VENDOR_ID VENDOR_ID
#define DFU_BCD_DEVICE BCD_DEVICE
#define DFU_MANUFACTURER_STR_INDEX offsetof(StringDescTable_t, vendorStr)/sizeof(char *)
#if (AUDIO_CLASS == 2)
#define DFU_PRODUCT_STR_INDEX offsetof(StringDescTable_t, productStr_Audio2)/sizeof(char *)
#else
#define DFU_PRODUCT_STR_INDEX offsetof(StringDescTable_t, productStr_Audio1)/sizeof(char *)
#endif
#endif
/* USB test mode support enabled by default (Required for compliance testing) */

View File

@@ -45,9 +45,9 @@ extern unsigned char mixSel[MAX_MIX_COUNT][MIX_INPUTS];
/* Global var for current frequency, set to default freq */
unsigned int g_curSamFreq = DEFAULT_FREQ;
//unsigned int g_curSamFreq48000Family = DEFAULT_FREQ % 48000 == 0;
#if 0
unsigned int g_curSamFreq48000Family = DEFAULT_FREQ % 48000 == 0;
/* Original feedback implementation */
long long g_curSamFreqMultiplier = (DEFAULT_FREQ * 512 * 4) / (DEFAULT_MCLK_FREQ);
#endif
@@ -131,6 +131,7 @@ static void setG_curSamFreqMultiplier(unsigned x)
}
#endif
#if (OUTPUT_VOLUME_CONTROL == 1) || (INPUT_VOLUME_CONTROL == 1)
/* Update master volume i.e. i.e update weights for all channels */
static void updateMasterVol( int unitID, chanend ?c_mix_ctl)
{
@@ -266,6 +267,7 @@ static void updateVol(int unitID, int channel, chanend ?c_mix_ctl)
}
}
}
#endif
/* Handles the audio class specific requests
* returns: XUD_RES_OKAY if request dealt with successfully without error,
@@ -275,7 +277,7 @@ static void updateVol(int unitID, int channel, chanend ?c_mix_ctl)
int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl
)
{
unsigned char buffer[512];
unsigned char buffer[128];
int unitID;
XUD_Result_t result;
unsigned datalength;
@@ -312,6 +314,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
return result;
}
#if MAX_FREQ != MIN_FREQ
if(datalength == 4)
{
/* Re-construct Sample Freq */
@@ -369,7 +372,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
/* Allow time for our feedback to stabilise*/
FeedbackStabilityDelay();
}
#endif /* MAX_FREQ != MIN_FREQ */
/* Send 0 Length as status stage */
XUD_DoSetRequestStatus(ep0_in);
}
@@ -514,6 +517,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
break;
}
#if (OUTPUT_VOLUME_CONTROL == 1) || (INPUT_VOLUME_CONTROL == 1)
/* Feature Units */
case FU_USBOUT:
case FU_USBIN:
@@ -629,6 +633,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
}
break; /* FU_USBIN */
#endif
#if defined(MIXER) && (MAX_MIX_COUNT > 0)
case ID_XU_OUT:
@@ -1076,7 +1081,7 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp
*/
XUD_Result_t result;
unsigned char buffer[1024];
unsigned char buffer[128];
unsigned length;
/* Host to Device */
@@ -1094,7 +1099,7 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp
{
return result;
}
#if (MAX_FREQ != MIN_FREQ)
if(controlSelector == SAMPLING_FREQ_CONTROL)
{
/* Expect length 3 for sample rate */
@@ -1116,22 +1121,6 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp
if(curSamFreq48000Family || curSamFreq44100Family)
{
g_curSamFreq = newSampleRate;
#if 0
/* Original feedback implementation */
int newMasterClock;
if(g_curSamFreq48000Family)
{
newMasterClock = MCLK_48;
}
else
{
newMasterClock = MCLK_441;
}
setG_curSamFreqMultiplier((g_curSamFreq*512*4)/newMasterClock);
#endif
/* Instruct audio thread to change sample freq */
outuint(c_audioControl, SET_SAMPLE_FREQ);
@@ -1147,6 +1136,9 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp
return XUD_SetBuffer(ep0_in, buffer, 0);
}
}
#else
return XUD_SetBuffer(ep0_in, buffer, 0);
#endif
}
break;
}
@@ -1171,12 +1163,13 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp
int AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl
)
{
unsigned char buffer[1024];
unsigned char buffer[128];
unsigned unitID;
XUD_Result_t result;
/* Inspect request */
/* Note we could check sp.bmRequestType.Direction if we wanted to be really careful */
#if (OUTPUT_VOLUME_CONTROL == 1) || (INPUT_VOLUME_CONTROL == 1)
switch(sp.bRequest)
{
case UAC_B_REQ_SET_CUR:
@@ -1288,7 +1281,7 @@ int AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
buffer[1] = (VOLUME_RES_MIXER >> 8);
return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength);
}
#endif
return 1;
}
#endif

View File

@@ -35,13 +35,14 @@ typedef struct
STR_TABLE_ENTRY(vendorStr);
STR_TABLE_ENTRY(serialStr);
#if (AUDIO_CLASS == 2)
/* Audio 2.0 Strings */
STR_TABLE_ENTRY(productStr_Audio2); /* Product string for Audio 2 */
STR_TABLE_ENTRY(outputInterfaceStr_Audio2); /* iInterface for streaming intefaces */
STR_TABLE_ENTRY(inputInterfaceStr_Audio2); /* iInterface for streaming intefaces */
STR_TABLE_ENTRY(usbInputTermStr_Audio2); /* Users sees as output from host */
STR_TABLE_ENTRY(usbOutputTermStr_Audio2); /* User sees as input to host */
#endif
#if defined (AUDIO_CLASS_FALLBACK) || (AUDIO_CLASS == 1)
/* Audio 1.0 Strings */
STR_TABLE_ENTRY(productStr_Audio1); /* Product string for Audio 1 */
@@ -50,6 +51,7 @@ typedef struct
STR_TABLE_ENTRY(usbInputTermStr_Audio1); /* Users sees as output from host */
STR_TABLE_ENTRY(usbOutputTermStr_Audio1); /* User sees as input to host */
#endif
#if (AUDIO_CLASS == 2)
STR_TABLE_ENTRY(clockSelectorStr); /* iClockSel */
STR_TABLE_ENTRY(internalClockSourceStr); /* iClockSource for internal clock */
#ifdef SPDIF_RX
@@ -58,6 +60,7 @@ typedef struct
#ifdef ADAT_RX
STR_TABLE_ENTRY(adatClockSourceStr); /* iClockSource for external S/PDIF clock */
#endif
#endif
#ifdef DFU
STR_TABLE_ENTRY(dfuStr); /* iInterface for DFU interface */
#endif
@@ -291,7 +294,9 @@ typedef struct
#if defined(MIXER) && (MAX_MIX_COUNT > 7)
STR_TABLE_ENTRY(mixOutStr_8);
#endif
#ifdef IAP
STR_TABLE_ENTRY(iAPInterfaceStr);
#endif
#ifdef IAP_EA_NATIVE_TRANS
STR_TABLE_ENTRY(iAP_EANativeTransport_InterfaceStr);
#endif
@@ -302,12 +307,13 @@ StringDescTable_t g_strTable =
.langID = "\x09\x04", /* US English */
.vendorStr = VENDOR_STR,
.serialStr = "",
#if (AUDIO_CLASS == 2)
.productStr_Audio2 = PRODUCT_STR_A2,
.outputInterfaceStr_Audio2 = APPEND_PRODUCT_STR_A2(),
.inputInterfaceStr_Audio2 = APPEND_PRODUCT_STR_A2(),
.usbInputTermStr_Audio2 = APPEND_PRODUCT_STR_A2(),
.usbOutputTermStr_Audio2 = APPEND_PRODUCT_STR_A2(),
#endif
#if defined (AUDIO_CLASS_FALLBACK) || (AUDIO_CLASS == 1)
.productStr_Audio1 = PRODUCT_STR_A1,
.outputInterfaceStr_Audio1 = APPEND_PRODUCT_STR_A1(),
@@ -315,6 +321,7 @@ StringDescTable_t g_strTable =
.usbInputTermStr_Audio1 = APPEND_PRODUCT_STR_A1(),
.usbOutputTermStr_Audio1 = APPEND_PRODUCT_STR_A1(),
#endif
#if (AUDIO_CLASS == 2)
.clockSelectorStr = APPEND_VENDOR_STR(Clock Selector),
.internalClockSourceStr = APPEND_VENDOR_STR(Internal Clock),
#ifdef SPDIF_RX
@@ -323,6 +330,7 @@ StringDescTable_t g_strTable =
#ifdef ADAT_RX
.adatClockSourceStr = APPEND_VENDOR_STR(ADAT Clock),
#endif
#endif
#ifdef DFU
.dfuStr = APPEND_VENDOR_STR(DFU),
#endif
@@ -368,7 +376,9 @@ StringDescTable_t g_strTable =
#if defined(MIXER) && (MAX_MIX_COUNT > 8)
#error
#endif
#ifdef IAP
.iAPInterfaceStr = "iAP Interface",
#endif
#ifdef IAP_EA_NATIVE_TRANS
.iAP_EANativeTransport_InterfaceStr = IAP2_EA_NATIVE_TRANS_PROTOCOL_NAME,
#endif
@@ -397,6 +407,7 @@ USB_Descriptor_Device_t devDesc_Audio1 =
};
#endif
#if (AUDIO_CLASS == 2)
/* Device Descriptor for Audio Class 2.0 (Assumes High-Speed ) */
USB_Descriptor_Device_t devDesc_Audio2 =
{
@@ -438,7 +449,7 @@ unsigned char devDesc_Null[] =
0, /* 16 iSerialNumber : Index of serial number decriptor */
0x01 /* 17 bNumConfigurations : Number of possible configs */
};
#endif
/****** Device Qualifier Descriptors *****/
@@ -751,7 +762,7 @@ typedef struct
}__attribute__((packed)) USB_Config_Descriptor_Audio2_t;
#if 1
#if (AUDIO_CLASS == 2)
USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
{
.Config =
@@ -2252,7 +2263,10 @@ const unsigned num_freqs_a1 = MAX(3, (0
#define NUM_CONTROL_INTERFACES 0
#endif
#define AC_TOTAL_LENGTH (AC_LENGTH + (INPUT_INTERFACES_A1 * (17 + NUM_USB_CHAN_IN_FS + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (17 + NUM_USB_CHAN_OUT_FS + (num_freqs_a1 *3))))
#define AC_TOTAL_LENGTH (AC_LENGTH + \
(INPUT_INTERFACES_A1 * (9 + (7* INPUT_VOLUME_CONTROL) + (NUM_USB_CHAN_IN_FS * INPUT_VOLUME_CONTROL) + num_freqs_a1 * 3)) +\
(OUTPUT_INTERFACES_A1 * (9 + (7 * OUTPUT_VOLUME_CONTROL) + (NUM_USB_CHAN_OUT_FS * OUTPUT_VOLUME_CONTROL) + (num_freqs_a1 *3))))
#define STREAMING_INTERFACES (INPUT_INTERFACES_A1 + OUTPUT_INTERFACES_A1)
/* Number of interfaces for Audio 1.0 (+1 for control ) */
@@ -2297,7 +2311,7 @@ unsigned char cfgDesc_Audio1[] =
USB_CLASS_AUDIO,
UAC_INT_SUBCLASS_AUDIOCONTROL,
0x00, /* Unused */
8, /* iInterface - re-use iProduct */
offsetof(StringDescTable_t, productStr_Audio1)/sizeof(char *), /* iInterface - re-use iProduct */
/* CS (Class Specific) AudioControl interface header descriptor (4.3.2) */
AC_LENGTH,
@@ -2325,8 +2339,9 @@ unsigned char cfgDesc_Audio1[] =
NUM_USB_CHAN_OUT_FS, /* bNrChannels */
0x03, 0x00, /* wChannelConfig */
offsetof(StringDescTable_t, outputChanStr_1)/sizeof(char *), /* iChannelNames */
11, /* iTerminal */
offsetof(StringDescTable_t, usbInputTermStr_Audio1)/sizeof(char *), /* iTerminal */
#if (OUTPUT_VOLUME_CONTROL == 1)
/* CS_Interface class specific AC interface feature unit descriptor - mute & volume for dac */
(8 + NUM_USB_CHAN_OUT_FS),
UAC_CS_DESCTYPE_INTERFACE,
@@ -2364,6 +2379,7 @@ unsigned char cfgDesc_Audio1[] =
#error NUM_USB_CHAN_OUT_FS > 8 currently supported
#endif
0x00, /* String table index */
#endif
/* CS_Interface Output Terminal Descriptor - Analogue out to speaker */
0x09,
@@ -2372,7 +2388,11 @@ unsigned char cfgDesc_Audio1[] =
0x06, /* Terminal ID */
0x01, 0x03, /* Type - streaming out, speaker */
0x00, /* Associated terminal - unused */
0x0A, /* sourceID */
#if (OUTPUT_VOLUME_CONTROL == 1)
0x0A, /* sourceID - FU */
#else
0x01, /* sourceID - IT */
#endif
0x00, /* Unused */
#endif
@@ -2387,7 +2407,7 @@ unsigned char cfgDesc_Audio1[] =
NUM_USB_CHAN_IN_FS, /* bNrChannels */
0x03, 0x00, /* wChannelConfigs */
offsetof(StringDescTable_t, inputChanStr_1)/sizeof(char *), /* iChannelNames */
12, /* iTerminal */
offsetof(StringDescTable_t, usbOutputTermStr_Audio1)/sizeof(char *), /* iTerminal */
/* CS_Interface Output Terminal Descriptor - USB Streaming Device to Host*/
0x09,
@@ -2396,9 +2416,14 @@ unsigned char cfgDesc_Audio1[] =
0x07, /* Terminal ID */
0x01, 0x01, /* Type - streaming */
0x01, /* Associated terminal - unused */
0x0B, /* sourceID - from selector unit ?? */
#if INPUT_VOLUME_CONTROL
0x0B, /* sourceID - FU */
#else
0x02, /* sourceID - IT */
#endif
0x00, /* Unused */
#if (INPUT_VOLUME_CONTROL == 1)
/* CS_Interface class specific AC interface feature unit descriptor - mute & volume for adc */
(8 + NUM_USB_CHAN_IN_FS),
UAC_CS_DESCTYPE_INTERFACE,
@@ -2436,6 +2461,7 @@ unsigned char cfgDesc_Audio1[] =
#endif
0x00, /* String table index */
#endif
#endif
#if (NUM_USB_CHAN_OUT > 0)
/* Standard AS Interface Descriptor (4.5.1) */
@@ -2447,7 +2473,7 @@ unsigned char cfgDesc_Audio1[] =
0x01, /* bInterfaceClass - AUDIO */
0x02, /* bInterfaceSubclass - AUDIO_STREAMING */
0x00, /* bInterfaceProtocol - Not used */
0x09, /* iInterface */
offsetof(StringDescTable_t, outputInterfaceStr_Audio1)/sizeof(char *), /* iInterface */
/* Standard As Interface Descriptor (4.5.1) */
0x09,
@@ -2462,7 +2488,7 @@ unsigned char cfgDesc_Audio1[] =
0x01, /* Interface class - AUDIO */
0x02, /* subclass - AUDIO_STREAMING */
0x00, /* Unused */
0x09, /* String table index */
offsetof(StringDescTable_t, outputInterfaceStr_Audio1)/sizeof(char *), /* iInterface */
/* Class-Specific AS Interface Descriptor (4.5.2) */
0x07,
@@ -2580,7 +2606,7 @@ unsigned char cfgDesc_Audio1[] =
0x01, /* Interface class - AUDIO */
0x02, /* subclass - AUDIO_STREAMING */
0x00, /* Unused */
0x0A, /* iInterface */
offsetof(StringDescTable_t, inputInterfaceStr_Audio1)/sizeof(char *),
/* Standard Interface Descriptor - Audio streaming IN */
0x09,
@@ -2591,7 +2617,7 @@ unsigned char cfgDesc_Audio1[] =
0x01, /* Interface class - AUDIO */
0x02, /* Subclass - AUDIO_STREAMING */
0x00, /* Unused */
0x0A, /* iInterface*/
offsetof(StringDescTable_t, inputInterfaceStr_Audio1)/sizeof(char *),
/* CS_Interface AC interface header descriptor */
0x07,
@@ -2688,7 +2714,7 @@ unsigned char cfgDesc_Audio1[] =
#ifdef XVSM
/* Standard DFU class Interface descriptor */
0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */
0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */
0x04, /* 1 bDescriptorType : INTERFACE descriptor. (field size 1 bytes) */
(OUTPUT_INTERFACES_A1 + 2), /* bInterfaceNumber */
0x00, /* 3 bAlternateSetting : Index of this setting. (field size 1 bytes) */

View File

@@ -206,6 +206,8 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
XUD_ep ep0_out = XUD_InitEp(c_ep0_out);
XUD_ep ep0_in = XUD_InitEp(c_ep0_in);
#if 0
/* Dont need to init globals.. */
/* Init tables for volumes (+ 1 for master) */
for(int i = 0; i < NUM_USB_CHAN_OUT + 1; i++)
{
@@ -218,7 +220,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
volsIn[i] = 0;
mutesIn[i] = 0;
}
#endif
VendorRequests_Init(VENDOR_REQUESTS_PARAMS);
#ifdef MIXER
@@ -295,7 +297,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
{
/* Returns XUD_RES_OKAY for success, XUD_RES_RST for bus reset */
XUD_Result_t result = USB_GetSetupPacket(ep0_out, ep0_in, &sp);
if (result == XUD_RES_OKAY)
{
result = XUD_RES_ERR;
@@ -311,7 +313,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
switch (sp.wIndex)
{
/* Check for audio stream from host start/stop */
#if (NUM_USB_CHAN_OUT > 0)
#if (NUM_USB_CHAN_OUT > 0) && (AUDIO_CLASS == 2)
case INTERFACE_NUMBER_AUDIO_OUTPUT:
/* Check the alt is in range */
if(sp.wValue <= OUTPUT_FORMAT_COUNT)
@@ -346,7 +348,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
break;
#endif
#if (NUM_USB_CHAN_IN > 0)
#if (NUM_USB_CHAN_IN > 0) && (AUDIO_CLASS == 2)
case INTERFACE_NUMBER_AUDIO_INPUT:
/* Check the alt is in range */
if(sp.wValue <= INPUT_FORMAT_COUNT)
@@ -641,6 +643,8 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
if (!DFU_mode_active)
{
#endif
printintln(2);
#ifdef AUDIO_CLASS_FALLBACK
/* Return Audio 2.0 Descriptors with Audio 1.0 as fallback */
result = USB_StandardRequests(ep0_out, ep0_in,

View File

@@ -19,9 +19,15 @@
#define portout(a,b) {__asm__ __volatile__("out res[%0], %1": : "r" (a) , "r" (b));}
#ifdef DFU_FLASH_DEVICE
#ifdef QUAD_SPI_FLASH
/* Using specified flash device rather than all supported in tools */
fl_QuadDeviceSpec flash_devices[] = {DFU_FLASH_DEVICE};
#else
/* Using specified flash device rather than all supported in tools */
fl_DeviceSpec flash_devices[] = {DFU_FLASH_DEVICE};
#endif
#endif
#ifdef QUAD_SPI_FLASH
/*
@@ -83,7 +89,11 @@ int flash_cmd_enable_ports()
#endif
#ifdef DFU_FLASH_DEVICE
#ifdef QUAD_SPI_FLASH
result = fl_connectToDevice(&p_qflash, flash_devices, 1);
#else
result = fl_connectToDevice(&p_flash, flash_devices, 1);
#endif
#else
/* Use default flash list */
#ifdef QUAD_SPI_FLASH

View File

@@ -317,9 +317,12 @@ VENDOR_REQUESTS_PARAMS_DEC_
c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst,
clk, 1, XUD_SPEED_HS, XUD_PWR_CFG);
#else
{
//set_core_high_priority_on();
XUD_Manager(c_xud_out, ENDPOINT_COUNT_OUT, c_xud_in, ENDPOINT_COUNT_IN,
c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst,
clk, 1, XUD_SPEED_FS, XUD_PWR_CFG);
}
#endif
/* USB Packet buffering Core */
@@ -672,7 +675,7 @@ int main()
#ifdef MIC_PROCESSING_USE_INTERFACE
on stdcore[PDM_TILE].core[0]: pdm_buffer(c_ds_output, c_pdm_pcm, i_mic_process);
#else
on stdcore[PDM_TILE]: pdm_buffer(c_ds_output, c_pdm_pcm);
on stdcore[PDM_TILE].core[0]: pdm_buffer(c_ds_output, c_pdm_pcm);
#endif
#endif

View File

@@ -29,4 +29,7 @@
#
EXCLUDE_FILES += descriptors_2.rst
MODULE_XCC_FLAGS += $(XCC_FLAGS) -falways-inline
#MODULE_XCC_FLAGS += $(XCC_FLAGS) -falways-inline
XCC_FLAGS_endpoint0.c = -Os -mno-dual-issue $(XCC_FLAGS)
XCC_FLAGS_dbcalc.xc = -Os -mno-dual-issue $(XCC_FLAGS)

View File

@@ -17,7 +17,7 @@
#include "mic_array.h"
#include "xua_pdm_mic.h"
#define MAX_DECIMATION_FACTOR 12
#define MAX_DECIMATION_FACTOR (96000/MIN_FREQ)
/* Hardware resources */
in port p_pdm_clk = PORT_PDM_CLK;
@@ -36,11 +36,11 @@ mic_array_frame_time_domain mic_audio[2];
void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio, client mic_process_if i_mic_process)
#else
#pragma unsafe arrays
[[combinable]]
void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio)
#endif
{
unsigned buffer;
int output[NUM_PDM_MICS];
unsigned samplerate;
#ifdef MIC_PROCESSING_USE_INTERFACE
@@ -126,7 +126,7 @@ void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio)
#ifdef MIC_PROCESSING_USE_INTERFACE
i_mic_process.transfer_buffers(current, output);
#else
user_pdm_process(current, output);
user_pdm_process(current);
#endif
int req;
while(1)
@@ -143,7 +143,7 @@ void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio)
#pragma loop unroll
for(int i = 0; i < NUM_PDM_MICS; i++)
{
c_audio <: output[i];
c_audio <: current->data[i][0];
}
}
@@ -154,7 +154,7 @@ void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio)
#ifdef MIC_PROCESSING_USE_INTERFACE
i_mic_process.transfer_buffers(current, output);
#else
user_pdm_process(current, output);
user_pdm_process(current);
#endif
}
else
@@ -177,7 +177,7 @@ void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio)
#ifdef MIC_PROCESSING_USE_INTERFACE
i_mic_process.transfer_buffers(current, output);
#else
user_pdm_process(current, output);
user_pdm_process(current);
#endif
}
break;

View File

@@ -14,15 +14,8 @@ void user_pdm_init()
void user_pdm_process() __attribute__ ((weak));
void user_pdm_process(mic_array_frame_time_domain * audio, int output[])
void user_pdm_process(mic_array_frame_time_domain * audio)
{
for(unsigned i=0; i<NUM_PDM_MICS; i++)
{
/* Simply copy input buffer to output buffer unmodified */
output[i] = audio->data[i][0];
}
return;
}

View File

@@ -26,11 +26,12 @@ void pdm_mic(streaming chanend c_ds_output[2]);
#else
/* Simple user hooks/call-backs */
void user_pdm_process(mic_array_frame_time_domain * unsafe audio, int output[]);
void user_pdm_process(mic_array_frame_time_domain * unsafe audio);
void user_pdm_init();
/* PDM interface and decimation cores */
[[combinable]]
void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio);
/* PDM interface and decimation cores */

View File

@@ -14,25 +14,52 @@
#endif
#define MAX(x,y) ((x)>(y) ? (x) : (y))
#define HS_PACKET_SIZE ((((MAX_FREQ+7999)/8000))+3) // Samples per channel
#define FS_PACKET_SIZE ((((MAX_FREQ_FS+999)/1000))+3) // Samples per channel
/* TODO use SLOTSIZE to potentially save memory */
#define BUFF_SIZE_OUT MAX(4 * HS_PACKET_SIZE * NUM_USB_CHAN_OUT, 4 * FS_PACKET_SIZE * NUM_USB_CHAN_OUT_FS)
#define BUFF_SIZE_IN MAX(4 * HS_PACKET_SIZE * NUM_USB_CHAN_IN, 4 * FS_PACKET_SIZE * NUM_USB_CHAN_IN_FS)
/* Note we could improve on this, for one subslot is set to 4 */
/* The *4 is conversion to bytes, note we're assuming a slotsize of 4 here whic is potentially as waste */
#define MAX_DEVICE_AUD_PACKET_SIZE_MULT_HS ((MAX_FREQ/8000+1)*4)
#define MAX_DEVICE_AUD_PACKET_SIZE_MULT_FS ((MAX_FREQ_FS/1000+1)*4)
/*** IN PACKET SIZES ***/
/* Max packet sizes in bytes. Note the +4 is because we store packet lengths in the buffer */
#define MAX_DEVICE_AUD_PACKET_SIZE_IN_HS (MAX_DEVICE_AUD_PACKET_SIZE_MULT_HS * NUM_USB_CHAN_IN + 4)
#define MAX_DEVICE_AUD_PACKET_SIZE_IN_FS (MAX_DEVICE_AUD_PACKET_SIZE_MULT_FS * NUM_USB_CHAN_IN_FS + 4)
#define MAX_DEVICE_AUD_PACKET_SIZE_IN (MAX(MAX_DEVICE_AUD_PACKET_SIZE_IN_FS, MAX_DEVICE_AUD_PACKET_SIZE_IN_HS))
/*** OUT PACKET SIZES ***/
#define MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS (MAX_DEVICE_AUD_PACKET_SIZE_MULT_HS * NUM_USB_CHAN_OUT + 4)
#define MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS (MAX_DEVICE_AUD_PACKET_SIZE_MULT_FS * NUM_USB_CHAN_OUT_FS + 4)
#define MAX_DEVICE_AUD_PACKET_SIZE_OUT (MAX(MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS, MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS))
/*** BUFFER SIZES ***/
#define BUFFER_PACKET_COUNT 3 /* How many packets too allow for in buffer - minimum is 3! */
#define BUFF_SIZE_OUT_HS MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS * BUFFER_PACKET_COUNT
#define BUFF_SIZE_OUT_FS MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS * BUFFER_PACKET_COUNT
#define BUFF_SIZE_IN_HS MAX_DEVICE_AUD_PACKET_SIZE_IN_HS * BUFFER_PACKET_COUNT
#define BUFF_SIZE_IN_FS MAX_DEVICE_AUD_PACKET_SIZE_IN_FS * BUFFER_PACKET_COUNT
#define BUFF_SIZE_OUT MAX(BUFF_SIZE_OUT_HS, BUFF_SIZE_OUT_FS)
#define BUFF_SIZE_IN MAX(BUFF_SIZE_IN_HS, BUFF_SIZE_IN_FS)
//#define OUT_BUFFER_PREFILL (MAX(NUM_USB_CHAN_OUT_FS*FS_PACKET_SIZE*3+4,NUM_USB_CHAN_OUT*HS_PACKET_SIZE*4+4)*1)
//#define IN_BUFFER_PREFILL (MAX(FS_PACKET_SIZE*2+4, HS_PACKET_SIZE*4+4)*2)
#define OUT_BUFFER_PREFILL (MAX(MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS, MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS))
#define IN_BUFFER_PREFILL (MAX(MAX_DEVICE_AUD_PACKET_SIZE_IN_HS, MAX_DEVICE_AUD_PACKET_SIZE_IN_FS)*2)
/* Maximum USB buffer size (1024 bytes + 1 word to store length) */
#define MAX_USB_AUD_PACKET_SIZE 1028
#define OUT_BUFFER_PREFILL (MAX(NUM_USB_CHAN_OUT_FS*FS_PACKET_SIZE*3+4,NUM_USB_CHAN_OUT*HS_PACKET_SIZE*4+4)*1)
#define IN_BUFFER_PREFILL (MAX(FS_PACKET_SIZE*2+4, HS_PACKET_SIZE*4+4)*2)
/* Volume and mute tables */
#ifndef OUT_VOLUME_IN_MIXER
#if !defined(OUT_VOLUME_IN_MIXER) && (OUTPUT_VOLUME_CONTROL == 1)
unsigned int multOut[NUM_USB_CHAN_OUT + 1];
static xc_ptr p_multOut;
#endif
#ifndef IN_VOLUME_IN_MIXER
#if !defined(IN_VOLUME_IN_MIXER) && (INPUT_VOLUME_CONTROL == 1)
unsigned int multIn[NUM_USB_CHAN_IN + 1];
static xc_ptr p_multIn;
#endif
@@ -41,20 +68,12 @@ static xc_ptr p_multIn;
unsigned g_numUsbChan_Out = NUM_USB_CHAN_OUT;
unsigned g_numUsbChan_In = NUM_USB_CHAN_IN;
/* Note we could improve on this, for one subslot is set to 4 */
#define MAX_DEVICE_AUD_PACKET_SIZE_MULT_HS ((MAX_FREQ/8000+1)*4)
#define MAX_DEVICE_AUD_PACKET_SIZE_MULT_FS ((MAX_FREQ_FS/1000+1)*4)
#define MAX_DEVICE_AUD_PACKET_SIZE_HS ((MAX_FREQ/8000+1)*NUM_USB_CHAN_IN*4)
#define MAX_DEVICE_AUD_PACKET_SIZE_FS ((MAX_FREQ_FS/1000+1)*NUM_USB_CHAN_IN_FS*4)
#define MAX_DEVICE_AUD_PACKET_SIZE (MAX(MAX_DEVICE_AUD_PACKET_SIZE_FS, MAX_DEVICE_AUD_PACKET_SIZE_HS))
/* Circular audio buffers */
unsigned outAudioBuff[BUFF_SIZE_OUT + (MAX_USB_AUD_PACKET_SIZE>>2) + 4];
unsigned audioBuffIn[BUFF_SIZE_IN + (MAX_DEVICE_AUD_PACKET_SIZE>>2) + 4];
unsigned outAudioBuff[(BUFF_SIZE_OUT >> 2)+ (MAX_DEVICE_AUD_PACKET_SIZE_OUT >> 0)];
unsigned audioBuffIn[(BUFF_SIZE_IN >> 2)+ (MAX_DEVICE_AUD_PACKET_SIZE_IN >> 0)];
unsigned inZeroBuff[(MAX_DEVICE_AUD_PACKET_SIZE>>2)+4];
/* Shift down accounts for bytes -> words */
unsigned inZeroBuff[(MAX_DEVICE_AUD_PACKET_SIZE_IN >> 2)];
void GetADCCounts(unsigned samFreq, int &min, int &mid, int &max);
@@ -91,8 +110,13 @@ xc_ptr g_aud_to_host_wrptr;
xc_ptr g_aud_to_host_dptr;
xc_ptr g_aud_to_host_rdptr;
xc_ptr g_aud_to_host_zeros;
#if (AUDIO_CLASS == 2)
int sampsToWrite = DEFAULT_FREQ/8000; /* HS assumed here. Expect to be junked during a overflow before stream start */
int totalSampsToWrite = DEFAULT_FREQ/8000;
#else
int sampsToWrite = DEFAULT_FREQ/1000; /* HS assumed here. Expect to be junked during a overflow before stream start */
int totalSampsToWrite = DEFAULT_FREQ/1000;
#endif
int aud_data_remaining_to_device = 0;
/* Audio over/under flow flags */
@@ -109,15 +133,21 @@ unsigned unpackData = 0;
unsigned packState = 0;
unsigned packData = 0;
/* Default to something sensible but the following are setup at stream start: */
/* Default to something sensible but the following are setup at stream start (unless UAC1 only..) */
#if (AUDIO_CLASS == 2)
unsigned g_curSubSlot_Out = HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES;
unsigned g_curSubSlot_In = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES;
/* Init to something sensible, but expect to be re-set before stream start */
#if (AUDIO_CLASS==2)
int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_HS;
#else
int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_FS;
unsigned g_curSubSlot_Out = FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES;
unsigned g_curSubSlot_In = FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES;
#endif
/* IN packet size. Init to something sensible, but expect to be re-set before stream start */
#if (AUDIO_CLASS==2)
int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_IN_HS;
#else
int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_IN_FS;
#endif
#pragma select handler
@@ -146,7 +176,7 @@ void handle_audio_request(chanend c_mix_out)
outSamps = g_aud_from_host_wrptr - g_aud_from_host_rdptr;
if (outSamps < 0)
{
outSamps += BUFF_SIZE_OUT*4;
outSamps += BUFF_SIZE_OUT;
}
/* If we have a decent number of samples, come out of underflow cond */
@@ -170,7 +200,6 @@ __builtin_unreachable();
{
#pragma xta endpoint "mixer_request"
int sample;
int mult;
int h;
unsigned l;
@@ -505,7 +534,7 @@ __builtin_unreachable();
space_left += datalength;
SET_SHARED_GLOBAL(g_aud_to_host_rdptr, rdPtr);
} while(space_left < (BUFF_SIZE_IN*4/2));
} while(space_left < (BUFF_SIZE_IN/2));
}
sampsToWrite = totalSampsToWrite;
@@ -594,22 +623,22 @@ void decouple(chanend c_mix_out
int t = array_to_xc_ptr(outAudioBuff);
#ifndef OUT_VOLUME_IN_MIXER
#if !defined(OUT_VOLUME_IN_MIXER) && (OUTPUT_VOLUME_CONTROL == 1)
p_multOut = array_to_xc_ptr(multOut);
#endif
#ifndef IN_VOLUME_IN_MIXER
#if !defined(IN_VOLUME_IN_MIXER) && (INPUT_VOLUME_CONTROL == 1)
p_multIn = array_to_xc_ptr(multIn);
#endif
aud_from_host_fifo_start = t;
aud_from_host_fifo_end = aud_from_host_fifo_start + BUFF_SIZE_OUT*4;
aud_from_host_fifo_end = aud_from_host_fifo_start + BUFF_SIZE_OUT;
g_aud_from_host_wrptr = aud_from_host_fifo_start;
g_aud_from_host_rdptr = aud_from_host_fifo_start;
t = array_to_xc_ptr(audioBuffIn);
aud_to_host_fifo_start = t;
aud_to_host_fifo_end = aud_to_host_fifo_start + BUFF_SIZE_IN*4;
aud_to_host_fifo_end = aud_to_host_fifo_start + BUFF_SIZE_IN;
g_aud_to_host_wrptr = aud_to_host_fifo_start;
g_aud_to_host_rdptr = aud_to_host_fifo_start;
g_aud_to_host_dptr = aud_to_host_fifo_start + 4;
@@ -622,14 +651,14 @@ void decouple(chanend c_mix_out
g_aud_to_host_zeros = t;
/* Init vol mult tables */
#ifndef OUT_VOLUME_IN_MIXER
#if !defined(OUT_VOLUME_IN_MIXER) && (OUTPUT_VOLUME_CONTROL == 1)
for (int i = 0; i < NUM_USB_CHAN_OUT + 1; i++)
{
asm volatile("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multOut),"r"(i));
}
#endif
#ifndef IN_VOLUME_IN_MIXER
#if !defined(IN_VOLUME_IN_MIXER) && (INPUT_VOLUME_CONTROL == 1)
for (int i = 0; i < NUM_USB_CHAN_IN + 1; i++)
{
asm volatile("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multIn),"r"(i));
@@ -664,10 +693,16 @@ void decouple(chanend c_mix_out
aud_to_host_flag = 0;
SET_SHARED_GLOBAL(g_aud_to_host_flag, aud_to_host_flag);
/* NOTE: IN EP not marked ready at this point - Initial size of zero buffer not known
/* NOTE: For UAC2 IN EP not marked ready at this point - Initial size of zero buffer not known
* since we don't know the USB bus-speed yet.
* The host will send a SetAltInterface before streaming which will lead to this core
* getting a SET_CHANNEL_COUNT_IN. This will setup the EP for the first packet */
#if (AUDIO_CLASS == 1)
/* For UAC1 we know we only run at FS */
/* Set buffer back to zeros buffer */
SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros);
SetupZerosSendBuffer(aud_to_host_usb_ep, sampFreq, g_curSubSlot_In);
#endif
#endif
while(1)
@@ -687,6 +722,7 @@ void decouple(chanend c_mix_out
/* Check for freq change or other update */
GET_SHARED_GLOBAL(tmp, g_freqChange_flag);
#if MIN_FREQ != MAX_FREQ
if (tmp == SET_SAMPLE_FREQ)
{
SET_SHARED_GLOBAL(g_freqChange_flag, 0);
@@ -734,7 +770,10 @@ void decouple(chanend c_mix_out
speedRem = 0;
continue;
}
else if(tmp == SET_STREAM_FORMAT_IN)
else
#endif
#if (AUDIO_CLASS == 2)
if(tmp == SET_STREAM_FORMAT_IN)
{
unsigned dataFormat, usbSpeed;
@@ -790,6 +829,7 @@ void decouple(chanend c_mix_out
SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start);
SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_fifo_start);
/* NOTE, this is potentially usefull for UAC1 */
unpackState = 0;
outUnderflow = 1;
@@ -819,6 +859,7 @@ void decouple(chanend c_mix_out
SET_SHARED_GLOBAL(g_freqChange, 0);
ENABLE_INTERRUPTS();
}
#endif
}
#if (NUM_USB_CHAN_OUT > 0)
@@ -865,7 +906,7 @@ void decouple(chanend c_mix_out
space_left = aud_from_host_fifo_end - g_aud_from_host_wrptr;
}
if (space_left <= 0 || space_left >= MAX_USB_AUD_PACKET_SIZE)
if (space_left <= 0 || space_left >= MAX_DEVICE_AUD_PACKET_SIZE_OUT)
{
SET_SHARED_GLOBAL(g_aud_from_host_buffer, aud_from_host_wrptr);
XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_wrptr+4);
@@ -890,8 +931,8 @@ void decouple(chanend c_mix_out
GET_SHARED_GLOBAL(aud_from_host_rdptr, g_aud_from_host_rdptr);
space_left = aud_from_host_rdptr - aud_from_host_wrptr;
if (space_left <= 0)
space_left += BUFF_SIZE_OUT*4;
if (space_left >= (BUFF_SIZE_OUT*4/2))
space_left += BUFF_SIZE_OUT;
if (space_left >= (BUFF_SIZE_OUT/2))
{
/* Come out of OUT overflow state */
outOverflow = 0;
@@ -907,10 +948,10 @@ void decouple(chanend c_mix_out
#if (NUM_USB_CHAN_IN > 0)
{
/* Check if buffer() has sent a packet to host - uses shared mem flag to save chanends */
int tmp;
GET_SHARED_GLOBAL(tmp, g_aud_to_host_flag);
int sentPkt;
GET_SHARED_GLOBAL(sentPkt, g_aud_to_host_flag);
//case inuint_byref(c_buf_in, tmp):
if (tmp)
if (sentPkt)
{
/* Signals that the IN endpoint has sent data from the passed buffer */
/* Reset flag */
@@ -928,7 +969,7 @@ void decouple(chanend c_mix_out
fill_level = aud_to_host_wrptr - aud_to_host_rdptr;
if (fill_level < 0)
fill_level += BUFF_SIZE_IN*4;
fill_level += BUFF_SIZE_IN;
if (fill_level >= IN_BUFFER_PREFILL)
{

View File

@@ -81,6 +81,7 @@
#define do_interrupt_handler(f,args) \
asm(ISSUE_MODE_SINGLE\
".align 4\n" \
".cc_top __"#f"_handler.function,__"#f"_handler\n" \
"__" #f "_handler:\n" \
"ENTSP_lu6 0\n" \
"kentsp " #args "/2*2 + 20\n" \
@@ -91,7 +92,8 @@
restore_state(f,args) \
"krestsp " #args "/2*2 + 20 \n" \
"__kret:\n" \
"kret\n");
"kret\n" \
".cc_bottom __"#f"_handler.function");
#define register_interrupt_handler(f, args, nstackwords) \
asm (" .section .dp.data, \"adw\", @progbits\n" \
@@ -99,7 +101,7 @@
" .globl __" #f "_handler\n" \
" .align 8\n" \
"__" #f "_kernel_stack:\n" \
" .space " #nstackwords ", 0\n" \
" .space " #nstackwords ", 0\n" \
"__" #f "_kernel_stack_end:\n" \
" .space 4\n"\
" .text\n"); \

View File

@@ -305,6 +305,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in,
{
unsigned cmd = inuint(c_aud_ctl);
#if MAX_FREQ != MIN_FREQ
if(cmd == SET_SAMPLE_FREQ)
{
unsigned receivedSampleFreq = inuint(c_aud_ctl);
@@ -344,7 +345,10 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in,
* handshake elsewhere */
SET_SHARED_GLOBAL(g_freqChange_sampFreq, receivedSampleFreq);
}
else if(cmd == SET_STREAM_FORMAT_IN)
else
#endif
#if (AUDIO_CLASS == 2)
if(cmd == SET_STREAM_FORMAT_IN)
{
unsigned formatChange_DataFormat = inuint(c_aud_ctl);
unsigned formatChange_NumChans = inuint(c_aud_ctl);
@@ -356,8 +360,10 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in,
SET_SHARED_GLOBAL(g_formatChange_DataFormat, formatChange_DataFormat);
SET_SHARED_GLOBAL(g_formatChange_SampRes, formatChange_SampRes);
}
/* FIXME when FB EP is enabled there is no inital XUD_SetReady */
else if (cmd == SET_STREAM_FORMAT_OUT)
{
XUD_BusSpeed_t busSpeed;
unsigned formatChange_DataFormat = inuint(c_aud_ctl);
unsigned formatChange_NumChans = inuint(c_aud_ctl);
@@ -385,6 +391,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in,
}
#endif
}
#endif
/* Pass on sample freq change to decouple() via global flag (saves a chanend) */
/* Note: freqChange flags now used to communicate other commands also */
SET_SHARED_GLOBAL0(g_freqChange, cmd); /* Set command */