Updates got v6.0

This commit is contained in:
Ross Owen
2012-08-24 14:35:29 +01:00
parent 5f18d3bbd9
commit af648bf3d2
9 changed files with 154 additions and 247 deletions

View File

@@ -13,6 +13,6 @@
* \param c_config An optional channel that will be passed on to the * \param c_config An optional channel that will be passed on to the
* CODEC configuration functions. * CODEC configuration functions.
*/ */
void audio(chanend c_in, chanend ?c_dig, chanend ?c_config); void audio(chanend c_in, chanend ?c_dig, chanend ?c_config, chanend ?c_adc);
#endif // __audio_h__ #endif // __audio_h__

View File

@@ -12,6 +12,7 @@
#include <xs1.h> #include <xs1.h>
#include <xclib.h> #include <xclib.h>
#include <print.h> #include <print.h>
#include <xs1_su.h>
#include "clocking.h" #include "clocking.h"
#include "audioports.h" #include "audioports.h"
@@ -19,6 +20,10 @@
#include "devicedefines.h" #include "devicedefines.h"
#include "SpdifTransmit.h" #include "SpdifTransmit.h"
extern out port p_test;
unsigned g_adcVal = 0;
//#define RAMP_CHECK 1 //#define RAMP_CHECK 1
//#pragma xta command "analyse path i2s_output_l i2s_output_r" //#pragma xta command "analyse path i2s_output_l i2s_output_r"
@@ -60,7 +65,7 @@ extern void device_reboot(void);
/* I2S delivery thread */ /* I2S delivery thread */
#pragma unsafe arrays #pragma unsafe arrays
unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_dig_rx) unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_dig_rx, chanend ?c_adc)
{ {
unsigned sample; unsigned sample;
#if NUM_USB_CHAN_OUT > 0 #if NUM_USB_CHAN_OUT > 0
@@ -76,6 +81,8 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
unsigned prev=0; unsigned prev=0;
int started = 0; int started = 0;
#endif #endif
unsigned test = 0;
#if NUM_USB_CHAN_IN > 0 #if NUM_USB_CHAN_IN > 0
for (int i=0;i<NUM_USB_CHAN_IN;i++) for (int i=0;i<NUM_USB_CHAN_IN;i++)
@@ -376,6 +383,9 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
} }
#endif #endif
#if defined(SPDIF) && (NUM_USB_CHAN_OUT > 0) #if defined(SPDIF) && (NUM_USB_CHAN_OUT > 0)
outuint(c_spd_out, samplesOut[SPDIF_TX_INDEX]); /* Forward sample to SPDIF txt thread */ outuint(c_spd_out, samplesOut[SPDIF_TX_INDEX]); /* Forward sample to SPDIF txt thread */
sample = samplesOut[SPDIF_TX_INDEX + 1]; sample = samplesOut[SPDIF_TX_INDEX + 1];
@@ -447,6 +457,8 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
#endif #endif
#if (I2S_CHANS_ADC != 0) #if (I2S_CHANS_ADC != 0)
/* Input previous L ADC sample */ /* Input previous L ADC sample */
index = 0; index = 0;
@@ -460,7 +472,15 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
#endif #endif
} }
#ifdef SU1_ADC
{
unsigned x;
x = inuint(c_adc);
inct(c_adc);
asm("stw %0, dp[g_adcVal]"::"r"(x));
}
#endif
#endif #endif
} }
return 0; return 0;
@@ -512,8 +532,14 @@ static unsigned dummy_deliver(chanend c_out) {
} }
return 0; return 0;
} }
#define SAMPLE_RATE 200000
#define NUMBER_CHANNELS 1
#define NUMBER_SAMPLES 100
#define NUMBER_WORDS ((NUMBER_SAMPLES * NUMBER_CHANNELS+1)/2)
#define SAMPLES_PER_PRINT 1
void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config)
void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
{ {
#ifdef SPDIF #ifdef SPDIF
chan c_spdif_out; chan c_spdif_out;
@@ -523,6 +549,39 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config)
unsigned divide; unsigned divide;
unsigned firstRun = 1; unsigned firstRun = 1;
#ifdef SU1_ADC
/* Setup galaxian ADC */
unsigned data[1], channel;
int r;
unsigned int vals[NUMBER_WORDS];
int cnt = 0;
int div;
unsigned val = 0;
int val2 = 0;
int adcOk = 0;
/* Enable adc on channel */
enable_xs1_su_adc_input(0, c);
/* General ADC control (enabled, 1 samples per packet, 32 bits per sample) */
data[0] = 0x10201;
data[0] = 0x30101;
r = write_periph_32(xs1_su, 2, 0x20, 1, data);
/* ADC needs a few clocks before it starts pumping out samples */
for(int i = 0; i< 10; i++)
{
p_lrclk <: val;
val = ~val;
{
timer t;
unsigned time;
t :> time;
t when timerafter(time+1000):> void;
}
}
#endif
#ifdef SPDIF #ifdef SPDIF
SpdifTransmitPortConfig(p_spdif_tx, clk_mst_spd, p_mclk); SpdifTransmitPortConfig(p_spdif_tx, clk_mst_spd, p_mclk);
#endif #endif
@@ -533,6 +592,10 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config)
/* Perform required CODEC/ADC/DAC initialisation */ /* Perform required CODEC/ADC/DAC initialisation */
CodecInit(c_config); CodecInit(c_config);
{
}
while(1) while(1)
{ {
@@ -598,7 +661,7 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config)
#else #else
null, null,
#endif #endif
divide, c_dig_rx); divide, c_dig_rx, c);
// Currently no more audio will happen after this point // Currently no more audio will happen after this point
if (curSamFreq == AUDIO_STOP_FOR_DFU) if (curSamFreq == AUDIO_STOP_FOR_DFU)

View File

@@ -326,6 +326,9 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, SetupPacket &sp, chanend
i_tmp = buffer[0] | (buffer[1] << 8) | buffer[2] << 16 | buffer[3] << 24; i_tmp = buffer[0] | (buffer[1] << 8) | buffer[2] << 16 | buffer[3] << 24;
/* Instruct audio thread to change sample freq */ /* Instruct audio thread to change sample freq */
if(i_tmp != g_curSamFreq)
{
g_curSamFreq = i_tmp; g_curSamFreq = i_tmp;
g_curSamFreq48000Family = g_curSamFreq % 48000 == 0; g_curSamFreq48000Family = g_curSamFreq % 48000 == 0;
@@ -349,7 +352,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, SetupPacket &sp, chanend
/* Wait for handshake back - i.e. pll locked and clocks okay */ /* Wait for handshake back - i.e. pll locked and clocks okay */
chkct(c_audioControl, XS1_CT_END); chkct(c_audioControl, XS1_CT_END);
}
/* Allow time for our feedback to stabalise*/ /* Allow time for our feedback to stabalise*/
{ {
timer t; timer t;

View File

@@ -1857,6 +1857,7 @@ unsigned char cfgDesc_Audio1[] =
#endif #endif
#if 0 #if 0
/* Standard DFU class Interface descriptor */ /* Standard DFU class Interface descriptor */
/* NOTE, DFU DISABLED FOR AUDIO CLASS 1.0 BY DEFAULT DUE TO WINDOWS REQUESTING DRIVER */
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) */ 0x04, /* 1 bDescriptorType : INTERFACE descriptor. (field size 1 bytes) */
(INPUT_INTERFACES+OUTPUT_INTERFACES+1), /* 2 bInterfaceNumber : Index of this interface. (field size 1 bytes) */ (INPUT_INTERFACES+OUTPUT_INTERFACES+1), /* 2 bInterfaceNumber : Index of this interface. (field size 1 bytes) */

View File

@@ -13,8 +13,8 @@
#include "usbaudio20.h" /* Defines from USB Audio 2.0 spec */ #include "usbaudio20.h" /* Defines from USB Audio 2.0 spec */
#include "devicedefines.h" #include "devicedefines.h"
#include "DescriptorRequests.h" /* This device's descriptors */ #include "DescriptorRequests.h" /* Standard descriptor requests */
#include "descriptors_2.h" /* Descriptors */ #include "descriptors_2.h" /* This devices descriptors */
#include "clockcmds.h" #include "clockcmds.h"
#include "audiostream.h" #include "audiostream.h"
#include "vendorrequests.h" #include "vendorrequests.h"
@@ -24,33 +24,19 @@
#include "hid.h" #include "hid.h"
#endif #endif
#define GLXID 0x0001 /* Some warnings.... */
#define PLL_CTRL_VAL ((1<<23) | (499<<8) | (2<<0))
void glx_link_setup(unsigned myid, unsigned glxid);
void glx_link_setup_with(unsigned myid, unsigned glxid, unsigned link_setup_val);
int write_glx_periph_word(unsigned destId, unsigned periphAddress, unsigned destRegAddr, unsigned data);
int read_glx_periph_word(unsigned dest_id, unsigned periph_addr, unsigned dest_reg_addr, unsigned &rd_data);
int read_glx_periph_reg(unsigned dest_id, unsigned periph_addr, unsigned dest_reg_addr, unsigned bad_format, unsigned data_size, char buf[]);
int write_glx_periph_reg(unsigned dest_id, unsigned periph_addr, unsigned dest_reg_addr, unsigned bad_packet, unsigned data_size, char buf[]);
void read_sswitch_reg_verify(unsigned coreid, unsigned reg, unsigned &data, unsigned failval);
void write_sswitch_reg_verify(unsigned coreid, unsigned reg, unsigned data, unsigned failval);
#define XS1_GLX_PERIPH_SCTH_ID 0x3 /* Windows does not have a built in DFU driver (windows will prompt), so warn that DFU will not be functional in Audio 1.0 mode */
/* Windows does not have a built in DFU driver (windows will prompt), so warn that DFU will not be functional in Audio 1.0 mode.Udi
* Of course, OSX is unaffected.
*/
#if ((AUDIO_CLASS==1) || defined(AUDIO_CLASS_FALLBACK)) && defined(DFU) #if ((AUDIO_CLASS==1) || defined(AUDIO_CLASS_FALLBACK)) && defined(DFU)
#warning DFU will require a seperate driver (but will be enabled) in AUDIO 1.0 mode #warning DFU will not be enabled in AUDIO 1.0 mode due to Windows requesting driver
#endif #endif
/* MIDI not supported in Audio 1.0 mode */ /* MIDI not supported in Audio 1.0 mode */
#if ((AUDIO_CLASS==1) || defined(AUDIO_CLASS_FALLBACK)) && defined(MIDI) #if ((AUDIO_CLASS==1) || defined(AUDIO_CLASS_FALLBACK)) && defined(MIDI)
#warning MIDI is not supported and will not be enabled in AUDIO 1.0 mode #warning MIDI is currently not supported and will not be enabled in AUDIO 1.0 mode
#endif #endif
/* If PID_DFU not defined, standard PID used.. this is probably what we want.. */
#ifndef PID_DFU #ifndef PID_DFU
#warning PID_DFU not defined, Using PID_AUDIO_2. This is probably fine! #warning PID_DFU not defined, Using PID_AUDIO_2. This is probably fine!
#endif #endif
@@ -900,12 +886,6 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
//outuint(c_audioControl, AUDIO_START_FROM_DFU); //outuint(c_audioControl, AUDIO_START_FROM_DFU);
DFU_mode_active = 0; DFU_mode_active = 0;
{
unsigned char wdata[1];
wdata[0] = 77;
write_glx_periph_reg(GLXID, XS1_GLX_PERIPH_SCTH_ID, 0x0, 0, 1, wdata);
}
// Send reboot command // Send reboot command
//outuint(c_audioControl, SET_SAMPLE_FREQ); //outuint(c_audioControl, SET_SAMPLE_FREQ);
//outuint(c_audioControl, AUDIO_REBOOT_FROM_DFU); //outuint(c_audioControl, AUDIO_REBOOT_FROM_DFU);

View File

@@ -23,13 +23,8 @@ void read_sswitch_reg_verify(unsigned coreid, unsigned reg, unsigned &data, unsi
void device_reboot_implementation(chanend spare) void device_reboot_implementation(chanend spare)
{ {
#ifdef ARCH_S #ifdef ARCH_S
/* Disconnect from bus */
unsigned wdata;
char wdatac[1];
write_glx_periph_word(GLXID, XS1_GLX_PERIPH_USB_ID, XS1_UIFM_FUNC_CONTROL_REG, 4); write_glx_periph_word(GLXID, XS1_GLX_PERIPH_USB_ID, XS1_UIFM_FUNC_CONTROL_REG, 4);
// Turn off All term resistors and d+ pullup
// Term select and opmode
#endif #endif
outct(spare, XS1_CT_END); // have to do this before freeing the chanend outct(spare, XS1_CT_END); // have to do this before freeing the chanend

View File

@@ -18,7 +18,6 @@
* *
**/ **/
#include <xs1.h> #include <xs1.h>
#include <print.h>
#include "xc_ptr.h" #include "xc_ptr.h"
#define NO_INLINE_MIDI_SELECT_HANDLER 1 #define NO_INLINE_MIDI_SELECT_HANDLER 1
#include "usb_midi.h" #include "usb_midi.h"
@@ -35,43 +34,6 @@
#include "vendor_hid.h" #include "vendor_hid.h"
#endif #endif
/* This function changes the buffer staged for an IN transaction.
* **It can only be used if you know that the IN transaction will not occur**
* Otherwise a race condition can occur.
*
*/
static inline void XUD_Change_ReadyIn_Buffer(XUD_ep e, unsigned bufferPtr, int len)
{
int chan_array_ptr;
int xud_chan;
int my_chan;
int tail;
printstr("TODO");
asm ("ldw %0, %1[0]":"=r"(chan_array_ptr):"r"(e));
asm ("ldw %0, %1[2]":"=r"(my_chan):"r"(e));
tail = len & 0x3;
bufferPtr += (len-tail);
tail <<= 5;
asm ("ldw %0, %1[1]":"=r"(xud_chan):"r"(e));
len >>= 2;
len = -len;
/* Store buffer pointer */
asm ("stw %0, %1[5]"::"r"(bufferPtr),"r"(e));
/* Store length */
asm ("stw %0, %1[3]"::"r"(len),"r"(e));
/* Mark EP ready with pointer */
asm ("stw %0, %1[0]"::"r"(xud_chan),"r"(chan_array_ptr));
}
#define MAX(x,y) ((x)>(y) ? (x) : (y)) #define MAX(x,y) ((x)>(y) ? (x) : (y))
#define MAX_CLASS_ONE_FREQ 96000 #define MAX_CLASS_ONE_FREQ 96000
#define MAX_CLASS_ONE_CHAN 2 #define MAX_CLASS_ONE_CHAN 2
@@ -82,17 +44,8 @@ static inline void XUD_Change_ReadyIn_Buffer(XUD_ep e, unsigned bufferPtr, int l
#define BUFF_SIZE_OUT MAX(4 * CLASS_TWO_PACKET_SIZE * NUM_USB_CHAN_OUT, 4 * CLASS_ONE_PACKET_SIZE * MAX_CLASS_ONE_CHAN) #define BUFF_SIZE_OUT MAX(4 * CLASS_TWO_PACKET_SIZE * NUM_USB_CHAN_OUT, 4 * CLASS_ONE_PACKET_SIZE * MAX_CLASS_ONE_CHAN)
#define BUFF_SIZE_IN MAX(4 * CLASS_TWO_PACKET_SIZE * NUM_USB_CHAN_IN, 4 * CLASS_ONE_PACKET_SIZE * MAX_CLASS_ONE_CHAN) #define BUFF_SIZE_IN MAX(4 * CLASS_TWO_PACKET_SIZE * NUM_USB_CHAN_IN, 4 * CLASS_ONE_PACKET_SIZE * MAX_CLASS_ONE_CHAN)
#define MAX_USB_AUD_PACKET_SIZE 1028 #define MAX_USB_AUD_PACKET_SIZE 1028
//#define OUT_BUFFER_PREFILL (2*4*BUFF_SIZE_OUT/3)
//#define OUT_BUFFER_PREFILL MAX(CLASS_ONE_PACKET_SIZE*3+4,CLASS_TWO_PACKET_SIZE*4+4)*2
//#define IN_BUFFER_PREFILL MAX(CLASS_ONE_PACKET_SIZE*3+4,CLASS_TWO_PACKET_SIZE*4+4)*2
#define OUT_BUFFER_PREFILL (MAX(MAX_CLASS_ONE_CHAN*CLASS_ONE_PACKET_SIZE*3+4,NUM_USB_CHAN_OUT*CLASS_TWO_PACKET_SIZE*4+4)*1) #define OUT_BUFFER_PREFILL (MAX(MAX_CLASS_ONE_CHAN*CLASS_ONE_PACKET_SIZE*3+4,NUM_USB_CHAN_OUT*CLASS_TWO_PACKET_SIZE*4+4)*1)
#define IN_BUFFER_PREFILL (MAX(CLASS_ONE_PACKET_SIZE*3+4,CLASS_TWO_PACKET_SIZE*4+4)*2) #define IN_BUFFER_PREFILL (MAX(CLASS_ONE_PACKET_SIZE*3+4,CLASS_TWO_PACKET_SIZE*4+4)*2)
//#pragma xta command "add exclusion out_underflow"
//#pragma xta command "add exclusion freq_change"
//#pragma xta command "add exclusion print_err"is_as
//#pragma xta command "add exclusion out_soverflow"
//#pragma xta command "analyse path mixer_request mixer_request"
//#pragma xta command "set required - 5200 ns" /* 192kHz */
/* Volume and mute tables */ /* Volume and mute tables */
#ifndef OUT_VOLUME_IN_MIXER #ifndef OUT_VOLUME_IN_MIXER
@@ -122,49 +75,9 @@ unsigned inZeroBuff[(MAX_DEVICE_AUD_PACKET_SIZE>>2)+4];
unsigned ledVal = 1; unsigned ledVal = 1;
unsigned dir = 0; unsigned dir = 0;
void led(chanend ?c_led)
{
if(dir == 0)
ledVal <<= 1;
else
ledVal >>= 1;
if(ledVal == 0b10000000 || ledVal == 1)
dir = !dir;
if (!isnull(c_led)) {
c_led <: ledVal;
}
}
/* Returns the max and min packet sizes to send back to host for a given sample frequency
* See page 13 of USB Audio Device Class Definitions for Audio Data Formats Spec (v2.0)
*
* Audio samples per frame = INT(sampFreq/frametime); Variation allowed is + 1;
*
* For HS frame time = 8 * 1000
*
* so n = INT(SampFreq/8000) | INT (SampFreq/8000) + 1
*
* In the case where INT(SampFreq/8000) == SampFreq/8000) n may vary between
*
* INT(SamFreq/8000) - 1 | INT(SampFreq/8000) | INT (SampFreq/8000) + 1
*
* Note: Assumes HS (i.e. 8 frames per 1ms)
*
* Examples:
* 44100: min: 5 max: 6
* 48000: min: 5 max: 7
* 96000: min: 11 max: 13
* 88200: min: 11 max: 12
* 176400: min: 22 max: 23
* 192000: min: 23 max: 25
*
* Note: This function uses the multiple return value feature of XC
*/
void GetADCCounts(unsigned samFreq, int &min, int &mid, int &max); void GetADCCounts(unsigned samFreq, int &min, int &mid, int &max);
#ifdef IAP
static inline void swap(xc_ptr &a, xc_ptr &b) static inline void swap(xc_ptr &a, xc_ptr &b)
{ {
xc_ptr tmp; xc_ptr tmp;
@@ -174,50 +87,31 @@ static inline void swap(xc_ptr &a, xc_ptr &b)
return; return;
} }
// shared global midi buffering variables
#if 0
//#ifdef MIDI
unsigned g_midi_from_host_flag = 0;
unsigned g_midi_to_host_flag = 0;
int midi_to_host_usb_ep = 0;
int midi_from_host_usb_ep = 0;
#endif
#ifdef IAP
unsigned g_iap_reset = 0; unsigned g_iap_reset = 0;
unsigned g_iap_from_host_flag = 0; unsigned g_iap_from_host_flag = 0;
unsigned g_iap_to_host_flag = 0; unsigned g_iap_to_host_flag = 0;
int iap_to_host_usb_ep = 0; int iap_to_host_usb_ep = 0;
int iap_to_host_int_usb_ep = 0; int iap_to_host_int_usb_ep = 0;
int iap_from_host_usb_ep = 0; int iap_from_host_usb_ep = 0;
unsigned int g_iap_to_host_buffer_A[MAX_IAP_PACKET_SIZE/4+4];
unsigned int g_iap_to_host_buffer_B[MAX_IAP_PACKET_SIZE/4+4];
int g_iap_from_host_buffer[MAX_IAP_PACKET_SIZE/4+4];
unsigned g_zero_buffer[1];
#endif
#ifdef HID_CONTROLS
extern in port p_but;
unsigned char g_hidData[16] = {0};
unsigned char g_hidFlag = 0;
unsigned g_ep_hid = 0;
#endif #endif
int aud_from_host_usb_ep = 0; int aud_from_host_usb_ep = 0;
int aud_to_host_usb_ep = 0; int aud_to_host_usb_ep = 0;
int int_usb_ep = 0; int int_usb_ep = 0;
#if 0
//#ifdef MIDI
unsigned int g_midi_to_host_buffer_A[MAX_USB_MIDI_PACKET_SIZE/4+4];
unsigned int g_midi_to_host_buffer_B[MAX_USB_MIDI_PACKET_SIZE/4+4];
int g_midi_from_host_buffer[MAX_USB_MIDI_PACKET_SIZE/4+4];
#endif
#ifdef IAP /* Shared global audio buffering variables */
unsigned int g_iap_to_host_buffer_A[MAX_IAP_PACKET_SIZE/4+4];
unsigned int g_iap_to_host_buffer_B[MAX_IAP_PACKET_SIZE/4+4];
int g_iap_from_host_buffer[MAX_IAP_PACKET_SIZE/4+4];
unsigned g_zero_buffer[1];
#endif
#ifdef HID_CONTROLS
extern in port p_but;
unsigned char g_hidData[16] = {0};
unsigned char g_hidFlag = 0;
unsigned g_ep_hid = 0;
#endif
// shared global aud buffering variables
unsigned g_aud_from_host_buffer; unsigned g_aud_from_host_buffer;
unsigned g_aud_to_host_buffer; unsigned g_aud_to_host_buffer;
@@ -229,13 +123,11 @@ unsigned g_freqChange_flag = 0;
unsigned g_freqChange_sampFreq; unsigned g_freqChange_sampFreq;
int speedRem = 0; int speedRem = 0;
xc_ptr aud_from_host_fifo_start; xc_ptr aud_from_host_fifo_start;
xc_ptr aud_from_host_fifo_end; xc_ptr aud_from_host_fifo_end;
xc_ptr g_aud_from_host_wrptr; xc_ptr g_aud_from_host_wrptr;
xc_ptr g_aud_from_host_rdptr; xc_ptr g_aud_from_host_rdptr;
xc_ptr aud_to_host_fifo_start; xc_ptr aud_to_host_fifo_start;
xc_ptr aud_to_host_fifo_end; xc_ptr aud_to_host_fifo_end;
xc_ptr g_aud_to_host_wrptr; xc_ptr g_aud_to_host_wrptr;
@@ -244,18 +136,14 @@ xc_ptr g_aud_to_host_rdptr;
xc_ptr g_aud_to_host_zeros; xc_ptr g_aud_to_host_zeros;
int sampsToWrite = 0; int sampsToWrite = 0;
int totalSampsToWrite = 0; int totalSampsToWrite = 0;
int aud_data_remaining_to_device = 0; int aud_data_remaining_to_device = 0;
/* Audio over/under flow flags */
/* Over/under flow flags */
unsigned outUnderflow = 1; unsigned outUnderflow = 1;
unsigned outOverflow = 0; unsigned outOverflow = 0;
unsigned inUnderflow = 1; unsigned inUnderflow = 1;
unsigned inOverflow = 0; unsigned inOverflow = 0;
int aud_req_in_count = 0; int aud_req_in_count = 0;
int aud_req_out_count = 0; int aud_req_out_count = 0;
@@ -273,7 +161,7 @@ int slotSize = 3; /* 3 bytes per sample for Audio Class 1.0 */
#pragma select handler #pragma select handler
#pragma unsafe arrays #pragma unsafe arrays
void handle_audio_request(chanend c_mix_out, chanend ?c_led) void handle_audio_request(chanend c_mix_out)
{ {
int outSamps; int outSamps;
int space_left; int space_left;
@@ -441,7 +329,6 @@ void handle_audio_request(chanend c_mix_out, chanend ?c_led)
read_via_xc_ptr(sample, g_aud_from_host_rdptr); read_via_xc_ptr(sample, g_aud_from_host_rdptr);
g_aud_from_host_rdptr+=4; g_aud_from_host_rdptr+=4;
#ifndef OUT_VOLUME_IN_MIXER #ifndef OUT_VOLUME_IN_MIXER
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i)); asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
{h, l} = macs(mult, sample, 0, 0); {h, l} = macs(mult, sample, 0, 0);
@@ -449,13 +336,11 @@ void handle_audio_request(chanend c_mix_out, chanend ?c_led)
outuint(c_mix_out, h); outuint(c_mix_out, h);
#else #else
outuint(c_mix_out, sample); outuint(c_mix_out, sample);
#endif #endif
} }
} }
else else
{ {
/* Buffering not underflow condition send out some samples...*/ /* Buffering not underflow condition send out some samples...*/
for(int i = 0; i < g_numUsbChanOut; i++) for(int i = 0; i < g_numUsbChanOut; i++)
{ {
@@ -491,14 +376,6 @@ void handle_audio_request(chanend c_mix_out, chanend ?c_led)
} }
unpackState++; unpackState++;
if(sample!=0)
{ //printhexln(sample);
//printintln(g_numUsbChanOut);
//printhexln(g_aud_from_host_rdptr);
//printintln(aud_data_remaining_to_device);
//while(1);
}
#ifndef OUT_VOLUME_IN_MIXER #ifndef OUT_VOLUME_IN_MIXER
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i)); asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
{h, l} = macs(mult, sample, 0, 0); {h, l} = macs(mult, sample, 0, 0);
@@ -601,7 +478,6 @@ void handle_audio_request(chanend c_mix_out, chanend ?c_led)
/* Handle any tail - incase a bad driver sent us a datalength not a multiple of chan count */ /* Handle any tail - incase a bad driver sent us a datalength not a multiple of chan count */
if (aud_data_remaining_to_device) if (aud_data_remaining_to_device)
{ {
printintln(aud_data_remaining_to_device);
/* Round up to nearest word */ /* Round up to nearest word */
aud_data_remaining_to_device +=3; aud_data_remaining_to_device +=3;
aud_data_remaining_to_device &= (~3); aud_data_remaining_to_device &= (~3);
@@ -629,14 +505,7 @@ void handle_audio_request(chanend c_mix_out, chanend ?c_led)
g_aud_from_host_rdptr+=4; g_aud_from_host_rdptr+=4;
} }
#ifdef DEBUG_LEDS
else
{
led(c_led);
} }
#endif
}
} }
@@ -835,9 +704,10 @@ void decouple(chanend c_mix_out,
int len; int len;
GET_SHARED_GLOBAL(p, g_aud_to_host_buffer); GET_SHARED_GLOBAL(p, g_aud_to_host_buffer);
read_via_xc_ptr(len, p); read_via_xc_ptr(len, p)
XUD_SetReady_InPtr(aud_to_host_usb_ep, g_aud_to_host_buffer, len); XUD_SetReady_InPtr(aud_to_host_usb_ep, g_aud_to_host_buffer, len);
aud_in_ready = 1;
} }
#endif #endif
@@ -883,9 +753,26 @@ void decouple(chanend c_mix_out,
aud_to_host_fifo_start); aud_to_host_fifo_start);
SET_SHARED_GLOBAL(sampsToWrite, 0); SET_SHARED_GLOBAL(sampsToWrite, 0);
SET_SHARED_GLOBAL(totalSampsToWrite, 0); SET_SHARED_GLOBAL(totalSampsToWrite, 0);
SET_SHARED_GLOBAL(g_aud_to_host_buffer,
g_aud_to_host_zeros);
/* Set buffer to send back to zeros buffer */
SET_SHARED_GLOBAL(g_aud_to_host_buffer,g_aud_to_host_zeros);
/* Update size of zeros buffer */
{
int min, mid, max, usb_speed;
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
GetADCCounts(sampFreq, min, mid, max);
if (usb_speed == XUD_SPEED_HS)
mid*=NUM_USB_CHAN_IN*4;
else
mid*=NUM_USB_CHAN_IN*3;
asm("stw %0, %1[0]"::"r"(mid),"r"(g_aud_to_host_zeros));
}
#if 1
//TODO RACE HERE
/* Check if we have an IN packet ready to go */ /* Check if we have an IN packet ready to go */
if (aud_in_ready) if (aud_in_ready)
{ {
@@ -895,11 +782,12 @@ void decouple(chanend c_mix_out,
GET_SHARED_GLOBAL(p, g_aud_to_host_buffer); GET_SHARED_GLOBAL(p, g_aud_to_host_buffer);
read_via_xc_ptr(len, p); read_via_xc_ptr(len, p);
/* Update the audio in buffer to send the correct
* length back to the host for the new sample rate */
//XUD_Change_ReadyIn_Buffer(aud_to_host_usb_ep, p+4, len); //XUD_Change_ReadyIn_Buffer(aud_to_host_usb_ep, p+4, len);
XUD_SetReady_InPtr(aud_to_host_usb_ep, p+4, len);
} }
#endif
/* Reset OUT buffer state */ /* Reset OUT buffer state */
outUnderflow = 1; outUnderflow = 1;
SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start); SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start);
@@ -964,28 +852,13 @@ void decouple(chanend c_mix_out,
/* Read datalength from buffer */ /* Read datalength from buffer */
read_via_xc_ptr(datalength, released_buffer); read_via_xc_ptr(datalength, released_buffer);
//printintln(datalength);
/* Ignore bad small packets */ /* Ignore bad small packets */
if ((datalength >= (g_numUsbChanOut * slotSize)) && (released_buffer == g_aud_from_host_wrptr)) if ((datalength >= (g_numUsbChanOut * slotSize)) && (released_buffer == g_aud_from_host_wrptr))
{ {
#if 0
for(int i = 0; i < (datalength+4); i++)
{
unsigned samp;
read_byte_via_xc_ptr(samp, aud_from_host_wrptr);
aud_from_host_wrptr+=1;
printint(i);
printhexln(samp);
}
#endif
/* Move the write pointer of the fifo on - round up to nearest word */ /* Move the write pointer of the fifo on - round up to nearest word */
aud_from_host_wrptr = aud_from_host_wrptr + ((datalength+3)&~0x3) + 4; aud_from_host_wrptr = aud_from_host_wrptr + ((datalength+3)&~0x3) + 4;
/* Wrap pointer */ /* Wrap pointer */
if (aud_from_host_wrptr >= aud_from_host_fifo_end) if (aud_from_host_wrptr >= aud_from_host_fifo_end)
{ {
@@ -1035,7 +908,6 @@ void decouple(chanend c_mix_out,
/* Come out of OUT overflow state */ /* Come out of OUT overflow state */
outOverflow = 0; outOverflow = 0;
SET_SHARED_GLOBAL(g_aud_from_host_buffer, aud_from_host_wrptr); SET_SHARED_GLOBAL(g_aud_from_host_buffer, aud_from_host_wrptr);
printintln(1);
//XUD_SetReady(aud_from_host_usb_ep, 1); //XUD_SetReady(aud_from_host_usb_ep, 1);
#ifdef DEBUG_LEDS #ifdef DEBUG_LEDS
led(c_led); led(c_led);

View File

@@ -1,5 +1,30 @@
extern unsigned int g_curUsbSpeed; extern unsigned int g_curUsbSpeed;
#define XUD_SPEED_HS 2 #define XUD_SPEED_HS 2
/* Returns the max and min packet sizes to send back to host for a given sample frequency
* See page 13 of USB Audio Device Class Definitions for Audio Data Formats Spec (v2.0)
*
* Audio samples per frame = INT(sampFreq/frametime); Variation allowed is + 1;
*
* For HS frame time = 8 * 1000
*
* so n = INT(SampFreq/8000) | INT (SampFreq/8000) + 1
*
* In the case where INT(SampFreq/8000) == SampFreq/8000) n may vary between
*
* INT(SamFreq/8000) - 1 | INT(SampFreq/8000) | INT (SampFreq/8000) + 1
*
* Note: Assumes HS (i.e. 8 frames per 1ms)
*
* Examples:
* 44100: min: 5 max: 6
* 48000: min: 5 max: 7
* 96000: min: 11 max: 13
* 88200: min: 11 max: 12
* 176400: min: 22 max: 23
* 192000: min: 23 max: 25
*
*/
void GetADCCounts(unsigned samFreq, int *min, int *mid, int *max) void GetADCCounts(unsigned samFreq, int *min, int *mid, int *max)
{ {
unsigned frameTime; unsigned frameTime;

View File

@@ -118,7 +118,6 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
#endif #endif
unsigned datalength;
unsigned tmp; unsigned tmp;
unsigned sampleFreq = 0; unsigned sampleFreq = 0;
unsigned lastClock; unsigned lastClock;
@@ -188,7 +187,6 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
while(usb_speed == 0) while(usb_speed == 0)
{ {
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed); GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
//printintln(usb_speed);
} }
GetADCCounts(DEFAULT_FREQ, min, mid, max); GetADCCounts(DEFAULT_FREQ, min, mid, max);
@@ -503,29 +501,12 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
/* Audio HOST -> DEVICE */ /* Audio HOST -> DEVICE */
case XUD_GetData_Select(c_aud_out, ep_aud_out, tmp): case XUD_GetData_Select(c_aud_out, ep_aud_out, tmp):
{ {
unsigned samp;
asm("#h->d aud data"); asm("#h->d aud data");
pktCount++;
if(pktCount ==3)
{
// asm("ecallf %0"::"r"(0));
}
GET_SHARED_GLOBAL(aud_from_host_buffer, g_aud_from_host_buffer); GET_SHARED_GLOBAL(aud_from_host_buffer, g_aud_from_host_buffer);
//printintln(tmp);
#if 0
for(int i = 0; i < (tmp); i++)
{
read_byte_via_xc_ptr(samp, aud_from_host_buffer);
aud_from_host_buffer+=1;
printint(i);
printhexln(samp);
}
#endif
write_via_xc_ptr(aud_from_host_buffer, tmp); write_via_xc_ptr(aud_from_host_buffer, tmp);
/* Sync with audio thread */ /* Sync with audio thread */
SET_SHARED_GLOBAL(g_aud_from_host_flag, 1); SET_SHARED_GLOBAL(g_aud_from_host_flag, 1);
} }
@@ -622,10 +603,6 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
datalength -= 3; datalength -= 3;
break; break;
default: default:
// // Case not handled before
// printstrln("Tail case not handled (tail, datalength)");
// printintln(tail);
// printintln(datalength);
break; break;
} }
@@ -700,8 +677,6 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
#endif #endif
#ifdef MIDI #ifdef MIDI
//select
// {
/* Received word from MIDI thread - Check for ACK or Data */ /* Received word from MIDI thread - Check for ACK or Data */
case midi_get_ack_or_data(c_midi, is_ack, datum): case midi_get_ack_or_data(c_midi, is_ack, datum):
if (is_ack) if (is_ack)
@@ -753,14 +728,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
} }
} }
break; break;
// default: #endif /* ifdef MIDI */
// break;
//}
#endif
} }
} }