added toplevel makefile for xpd

This commit is contained in:
dan
2014-01-22 11:00:41 +00:00
parent 7c42307440
commit 98b3bdba95
47 changed files with 2789 additions and 2778 deletions

View File

@@ -2,9 +2,9 @@
#define __DECOUPLE_H__
/** Manage the data transfer between the USB audio buffer and the
/** Manage the data transfer between the USB audio buffer and the
* Audio I/O driver.
*
*
* \param c_audio_out Channel connected to the audio() or mixer() threads
* \param c_clk_int Optional chanend connected to the clockGen() thread if present
*/

View File

@@ -22,7 +22,7 @@
#define OUT_BUFFER_PREFILL (MAX(NUM_USB_CHAN_OUT_A1*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)
/* Volume and mute tables */
/* Volume and mute tables */
#ifndef OUT_VOLUME_IN_MIXER
unsigned int multOut[NUM_USB_CHAN_OUT + 1];
static xc_ptr p_multOut;
@@ -70,14 +70,14 @@ int speedRem = 0;
xc_ptr aud_from_host_fifo_start;
xc_ptr aud_from_host_fifo_end;
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_end;
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;
xc_ptr g_aud_to_host_rdptr;
xc_ptr g_aud_to_host_zeros;
int sampsToWrite = 0;
int totalSampsToWrite = 0;
int aud_data_remaining_to_device = 0;
@@ -134,16 +134,16 @@ void handle_audio_request(chanend c_mix_out)
g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_CLASS_ONE;
}
#endif
/* If in overflow condition then receive samples and throw away */
if(inOverflow || sampsToWrite == 0)
{
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
{
(void) inuint(c_mix_out);
}
/* Calculate how much space left in buffer */
space_left = g_aud_to_host_rdptr - g_aud_to_host_wrptr;
@@ -153,7 +153,7 @@ void handle_audio_request(chanend c_mix_out)
}
/* Check if we can come out of overflow */
if (space_left > (BUFF_SIZE_IN*4/2))
if (space_left > (BUFF_SIZE_IN*4/2))
{
inOverflow = 0;
}
@@ -171,7 +171,7 @@ __builtin_unreachable();
#endif
unsigned ptr = g_aud_to_host_dptr;
for(int i = 0; i < g_numUsbChanIn; i++)
for(int i = 0; i < g_numUsbChanIn; i++)
{
/* Receive sample */
int sample = inuint(c_mix_out);
@@ -188,20 +188,20 @@ __builtin_unreachable();
sample = sample << 3;
#endif
/* Write into fifo */
write_via_xc_ptr(ptr, sample);
write_via_xc_ptr(ptr, sample);
ptr+=4;
}
/* Update global pointer */
g_aud_to_host_dptr = ptr;
break;
}
case 3:
#if (SAMPLE_SUBSLOT_SIZE_HS != 3) && (SAMPLE_SUBSLOT_SIZE_FS != 3)
__builtin_unreachable();
#endif
for(int i = 0; i < g_numUsbChanIn; i++)
for(int i = 0; i < g_numUsbChanIn; i++)
{
/* Receive sample */
int sample = inuint(c_mix_out);
@@ -215,28 +215,28 @@ __builtin_unreachable();
sample = h << 3;
#endif
/* Pack 3 byte samples */
switch (packState&0x3)
{
case 0:
switch (packState&0x3)
{
case 0:
packData = sample;
break;
case 1:
packData = (packData >> 8) | ((sample & 0xff00)<<16);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
write_via_xc_ptr(g_aud_to_host_dptr, sample>>16);
write_via_xc_ptr(g_aud_to_host_dptr, sample>>16);
packData = sample;
break;
case 2:
packData = (packData>>16) | ((sample & 0xffff00) << 8);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
packData = sample;
break;
case 3:
packData = (packData >> 24) | (sample & 0xffffff00);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
break;
}
packState++;
@@ -248,7 +248,7 @@ __builtin_unreachable();
#if (SAMPLE_SUBSLOT_SIZE_HS != 2) && (SAMPLE_SUBSLOT_SIZE_FS != 2)
__builtin_unreachable();
#endif
for(int i = 0; i < g_numUsbChanIn; i++)
for(int i = 0; i < g_numUsbChanIn; i++)
{
/* Receive sample */
int sample = inuint(c_mix_out);
@@ -270,12 +270,12 @@ __builtin_unreachable();
switch (packState&0x1)
{
case 0:
packData = sample;
packData = sample;
break;
case 1:
case 1:
packData = (packData>>16) | (sample & 0xffff0000);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
break;
}
}
@@ -283,24 +283,24 @@ __builtin_unreachable();
default:
__builtin_unreachable();
break;
break;
}
/* Input any remaining channels - past this thread we always operate on max channel count */
for(int i = 0; i < NUM_USB_CHAN_IN - g_numUsbChanIn; i++)
{
inuint(c_mix_out);
}
sampsToWrite--;
sampsToWrite--;
}
if(outUnderflow)
{
{
#pragma xta endpoint "out_underflow"
#if 0
/* We're still pre-buffering, send out 0 samps */
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
unsigned sample;
unsigned mode;
@@ -320,9 +320,9 @@ __builtin_unreachable();
{
outSamps += BUFF_SIZE_OUT*4;
}
/* If we have a decent number of samples, come out of underflow cond */
if(outSamps >= (OUT_BUFFER_PREFILL))
if(outSamps >= (OUT_BUFFER_PREFILL))
{
outUnderflow = 0;
outSamps++;
@@ -335,19 +335,19 @@ __builtin_unreachable();
case 4:
#if (SAMPLE_SUBSLOT_SIZE_HS != 4) && (SAMPLE_SUBSLOT_SIZE_FS != 4)
__builtin_unreachable();
#endif
#endif
/* Buffering not underflow condition send out some samples...*/
for(int i = 0; i < g_numUsbChanOut; i++)
for(int i = 0; i < g_numUsbChanOut; i++)
{
#pragma xta endpoint "mixer_request"
int sample;
int mult;
int h;
unsigned l;
read_via_xc_ptr(sample, g_aud_from_host_rdptr);
g_aud_from_host_rdptr+=4;
#ifndef OUT_VOLUME_IN_MIXER
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
@@ -363,13 +363,13 @@ __builtin_unreachable();
}
break;
case 3:
#if (SAMPLE_SUBSLOT_SIZE_HS != 3) && (SAMPLE_SUBSLOT_SIZE_FS != 3)
__builtin_unreachable();
#endif
#endif
/* Buffering not underflow condition send out some samples...*/
for(int i = 0; i < g_numUsbChanOut; i++)
for(int i = 0; i < g_numUsbChanOut; i++)
{
#pragma xta endpoint "mixer_request"
int sample;
@@ -378,12 +378,12 @@ __builtin_unreachable();
unsigned l;
/* Unpack 3 byte samples */
switch (unpackState&0x3)
switch (unpackState&0x3)
{
case 0:
read_via_xc_ptr(unpackData, g_aud_from_host_rdptr);
g_aud_from_host_rdptr+=4;
sample = unpackData << 8;
sample = unpackData << 8;
break;
case 1:
sample = (unpackData >> 16);
@@ -393,7 +393,7 @@ __builtin_unreachable();
break;
case 2:
sample = (unpackData >> 8);
read_via_xc_ptr(unpackData, g_aud_from_host_rdptr);
read_via_xc_ptr(unpackData, g_aud_from_host_rdptr);
g_aud_from_host_rdptr+=4;
sample = sample | (unpackData<< 24);
break;
@@ -402,7 +402,7 @@ __builtin_unreachable();
break;
}
unpackState++;
#ifndef OUT_VOLUME_IN_MIXER
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
@@ -418,25 +418,25 @@ __builtin_unreachable();
case 2:
#if (SAMPLE_SUBSLOT_SIZE_HS != 3) && (SAMPLE_SUBSLOT_SIZE_FS != 3)
__builtin_unreachable();
#endif
#endif
/* Buffering not underflow condition send out some samples...*/
for(int i = 0; i < g_numUsbChanOut; i++)
for(int i = 0; i < g_numUsbChanOut; i++)
{
#pragma xta endpoint "mixer_request"
int sample;
int mult;
int h;
unsigned l;
switch (unpackState&0x1)
{
case 0:
read_via_xc_ptr(unpackData, g_aud_from_host_rdptr);
sample = unpackData << 16;
sample = unpackData << 16;
break;
case 1:
case 1:
g_aud_from_host_rdptr+=4;
sample = unpackData & 0xffff0000;
sample = unpackData & 0xffff0000;
break;
}
unpackState++;
@@ -451,7 +451,7 @@ __builtin_unreachable();
#endif
}
break;
default:
__builtin_unreachable();
break;
@@ -463,18 +463,18 @@ __builtin_unreachable();
{
outuint(c_mix_out, 0);
}
/* 3/4 bytes per sample */
/* 3/4 bytes per sample */
aud_data_remaining_to_device -= (g_numUsbChanOut*g_slotSize);
}
if (!inOverflow)
if (!inOverflow)
{
if (sampsToWrite == 0)
if (sampsToWrite == 0)
{
int speed;
if (totalSampsToWrite)
if (totalSampsToWrite)
{
unsigned datasize = totalSampsToWrite * g_slotSize * g_numUsbChanIn;
@@ -482,7 +482,7 @@ __builtin_unreachable();
datasize = (datasize+3) & (~0x3);
g_aud_to_host_wrptr += 4+datasize;
if (g_aud_to_host_wrptr >= aud_to_host_fifo_end)
{
g_aud_to_host_wrptr = aud_to_host_fifo_start;
@@ -491,66 +491,66 @@ __builtin_unreachable();
/* Get feedback val - ideally this would be syncronised */
asm("ldw %0, dp[g_speed]" : "=r" (speed) :);
/* Calc packet size to send back based on our fb */
/* Calc packet size to send back based on our fb */
speedRem += speed;
totalSampsToWrite = speedRem >> 16;
speedRem &= 0xffff;
#if 0
if (usb_speed == XUD_SPEED_HS)
if (usb_speed == XUD_SPEED_HS)
{
if (totalSampsToWrite < 0 || totalSampsToWrite*4*g_numUsbChanIn > (MAX_DEVICE_AUD_PACKET_SIZE_CLASS_TWO))
if (totalSampsToWrite < 0 || totalSampsToWrite*4*g_numUsbChanIn > (MAX_DEVICE_AUD_PACKET_SIZE_CLASS_TWO))
{
totalSampsToWrite = 0;
}
}
else
else
{
if (totalSampsToWrite < 0 || totalSampsToWrite*3*NUM_USB_CHAN_IN_A1 > (MAX_DEVICE_AUD_PACKET_SIZE_CLASS_ONE))
if (totalSampsToWrite < 0 || totalSampsToWrite*3*NUM_USB_CHAN_IN_A1 > (MAX_DEVICE_AUD_PACKET_SIZE_CLASS_ONE))
{
totalSampsToWrite = 0;
}
}
#else
if (totalSampsToWrite < 0 || totalSampsToWrite * g_slotSize * g_numUsbChanIn > g_maxPacketSize)
if (totalSampsToWrite < 0 || totalSampsToWrite * g_slotSize * g_numUsbChanIn > g_maxPacketSize)
{
totalSampsToWrite = 0;
}
#endif
/* Calc slots left in fifo */
space_left = g_aud_to_host_rdptr - g_aud_to_host_wrptr;
/* Calc slots left in fifo */
space_left = g_aud_to_host_rdptr - g_aud_to_host_wrptr;
/* Mod and special case */
if (space_left <= 0 && g_aud_to_host_rdptr == aud_to_host_fifo_start)
{
space_left = aud_to_host_fifo_end - g_aud_to_host_wrptr;
}
if ((space_left <= 0) || (space_left > totalSampsToWrite*g_numUsbChanIn * 4 + 4))
{
if ((space_left <= 0) || (space_left > totalSampsToWrite*g_numUsbChanIn * 4 + 4))
{
/* Packet okay, write to fifo */
if (totalSampsToWrite)
if (totalSampsToWrite)
{
write_via_xc_ptr(g_aud_to_host_wrptr, totalSampsToWrite*g_slotSize*g_numUsbChanIn);
packState = 0;
g_aud_to_host_dptr = g_aud_to_host_wrptr + 4;
}
}
else
else
{
inOverflow = 1;
totalSampsToWrite = 0;
}
sampsToWrite = totalSampsToWrite;
sampsToWrite = totalSampsToWrite;
}
}
if (!outUnderflow && (aud_data_remaining_to_device<(g_slotSize*g_numUsbChanOut)))
if (!outUnderflow && (aud_data_remaining_to_device<(g_slotSize*g_numUsbChanOut)))
{
/* 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)
{
/* Round up to nearest word */
aud_data_remaining_to_device +=3 - (unpackState&0x3);
@@ -569,14 +569,14 @@ __builtin_unreachable();
}
outUnderflow = (g_aud_from_host_rdptr == g_aud_from_host_wrptr);
if (!outUnderflow)
{
if (!outUnderflow)
{
read_via_xc_ptr(aud_data_remaining_to_device, g_aud_from_host_rdptr);
unpackState = 0;
g_aud_from_host_rdptr+=4;
}
}
@@ -610,7 +610,7 @@ static void check_for_interrupt(chanend ?c_clk_int) {
//XUD_SetReady(int_usb_ep, 0);
//asm("ldaw %0, dp[g_intData]":"=r"(x));
//XUD_SetReady_In(int_usb_ep, g_intData, 6);
//XUD_SetReady_In(int_usb_ep, g_intData, 6);
}
break;
@@ -619,24 +619,24 @@ static void check_for_interrupt(chanend ?c_clk_int) {
}
}
unsigned char tmpBuffer[1026];
unsigned char tmpBuffer[1026];
#pragma unsafe arrays
void decouple(chanend c_mix_out,
chanend ?c_clk_int
#ifdef CHAN_BUFF_CTRL
, chanend c_buf_ctrl
#endif
#endif
)
{
{
unsigned sampFreq = DEFAULT_FREQ;
#ifdef OUTPUT
#ifdef OUTPUT
int aud_from_host_flag=0;
xc_ptr released_buffer;
#endif
#ifdef INPUT
int aud_to_host_flag = 0;
#endif
#endif
int t = array_to_xc_ptr(outAudioBuff);
int aud_in_ready = 0;
@@ -651,18 +651,18 @@ void decouple(chanend c_mix_out,
aud_from_host_fifo_start = t;
aud_from_host_fifo_end = aud_from_host_fifo_start + BUFF_SIZE_OUT*4;
g_aud_from_host_wrptr = aud_from_host_fifo_start;
g_aud_from_host_rdptr = 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;
g_aud_to_host_wrptr = aud_to_host_fifo_start;
g_aud_to_host_rdptr = aud_to_host_fifo_start;
g_aud_to_host_rdptr = aud_to_host_fifo_start;
t = array_to_xc_ptr(inZeroBuff);
g_aud_to_host_zeros = t;
/* Init interrupt report */
g_intData[0] = 0; // Class-specific, caused by interface
g_intData[1] = 1; // attribute: CUR
@@ -678,7 +678,7 @@ void decouple(chanend c_mix_out,
asm("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multOut),"r"(i));
}
#endif
#ifndef IN_VOLUME_IN_MIXER
for (int i = 0; i < NUM_USB_CHAN_IN + 1; i++)
{
@@ -698,11 +698,11 @@ void decouple(chanend c_mix_out,
#ifdef OUTPUT
// wait for usb_buffer to set up
while(!aud_from_host_flag)
while(!aud_from_host_flag)
{
GET_SHARED_GLOBAL(aud_from_host_flag, g_aud_from_host_flag);
}
aud_from_host_flag = 0;
SET_SHARED_GLOBAL(g_aud_from_host_flag, aud_from_host_flag);
@@ -713,11 +713,11 @@ void decouple(chanend c_mix_out,
#ifdef INPUT
// Wait for usb_buffer to set up
while(!aud_to_host_flag)
while(!aud_to_host_flag)
{
GET_SHARED_GLOBAL(aud_to_host_flag, g_aud_to_host_flag);
}
aud_to_host_flag = 0;
SET_SHARED_GLOBAL(g_aud_to_host_flag, aud_to_host_flag);
@@ -729,9 +729,9 @@ void decouple(chanend c_mix_out,
GET_SHARED_GLOBAL(p, g_aud_to_host_buffer);
read_via_xc_ptr(len, p)
XUD_SetReady_InPtr(aud_to_host_usb_ep, g_aud_to_host_buffer, len);
aud_in_ready = 1;
XUD_SetReady_InPtr(aud_to_host_usb_ep, g_aud_to_host_buffer, len);
aud_in_ready = 1;
}
#endif
@@ -762,24 +762,24 @@ void decouple(chanend c_mix_out,
}
#endif
if (!isnull(c_clk_int))
if (!isnull(c_clk_int))
{
check_for_interrupt(c_clk_int);
}
{
asm("#decouple-default");
/* Check for freq change or other update */
GET_SHARED_GLOBAL(tmp, g_freqChange_flag);
if (tmp == SET_SAMPLE_FREQ)
if (tmp == SET_SAMPLE_FREQ)
{
SET_SHARED_GLOBAL(g_freqChange_flag, 0);
GET_SHARED_GLOBAL(sampFreq, g_freqChange_sampFreq);
/* Pass on to mixer */
DISABLE_INTERRUPTS();
DISABLE_INTERRUPTS();
inuint(c_mix_out);
outct(c_mix_out, SET_SAMPLE_FREQ);
outuint(c_mix_out, sampFreq);
@@ -792,7 +792,7 @@ void decouple(chanend c_mix_out,
aud_to_host_fifo_start);
SET_SHARED_GLOBAL(sampsToWrite, 0);
SET_SHARED_GLOBAL(totalSampsToWrite, 0);
/* Set buffer to send back to zeros buffer */
SET_SHARED_GLOBAL(g_aud_to_host_buffer,g_aud_to_host_zeros);
@@ -801,7 +801,7 @@ void decouple(chanend c_mix_out,
int min, mid, max, usb_speed;
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
GetADCCounts(sampFreq, min, mid, max);
if (usb_speed == XUD_SPEED_HS)
if (usb_speed == XUD_SPEED_HS)
mid*=NUM_USB_CHAN_IN*4;
else
mid*=NUM_USB_CHAN_IN_A1*3;
@@ -815,23 +815,23 @@ void decouple(chanend c_mix_out,
{
xc_ptr p;
int len;
GET_SHARED_GLOBAL(p, g_aud_to_host_buffer);
read_via_xc_ptr(len, p);
read_via_xc_ptr(len, p);
/* Update packet size */
XUD_SetReady_InPtr(aud_to_host_usb_ep, p+4, len);
}
/* Reset OUT buffer state */
/* Reset OUT buffer state */
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);
SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_fifo_start);
SET_SHARED_GLOBAL(aud_data_remaining_to_device, 0);
if(outOverflow)
{
/* If we were previously in overflow we wont have marked as ready */
/* If we were previously in overflow we wont have marked as ready */
XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_fifo_start+4);
outOverflow = 0;
}
@@ -842,7 +842,7 @@ void decouple(chanend c_mix_out,
SET_SHARED_GLOBAL(g_freqChange, 0);
asm("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END));
ENABLE_INTERRUPTS();
speedRem = 0;
@@ -851,11 +851,11 @@ void decouple(chanend c_mix_out,
else if(tmp == SET_CHAN_COUNT_IN)
{
/* Change in IN channel count */
DISABLE_INTERRUPTS();
DISABLE_INTERRUPTS();
SET_SHARED_GLOBAL(g_freqChange_flag, 0);
GET_SHARED_GLOBAL(g_numUsbChanIn, g_freqChange_sampFreq); /* Misuse of g_freqChange_sampFreq */
/* Reset IN buffer state */
/* Reset IN buffer state */
inOverflow = 0;
inUnderflow = 1;
SET_SHARED_GLOBAL(g_aud_to_host_rdptr, aud_to_host_fifo_start);
@@ -863,29 +863,29 @@ void decouple(chanend c_mix_out,
SET_SHARED_GLOBAL(sampsToWrite, 0);
SET_SHARED_GLOBAL(totalSampsToWrite, 0);
SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros);
SET_SHARED_GLOBAL(g_freqChange, 0);
ENABLE_INTERRUPTS();
}
else if(tmp == SET_CHAN_COUNT_OUT)
{
/* Change in OUT channel count */
DISABLE_INTERRUPTS();
DISABLE_INTERRUPTS();
SET_SHARED_GLOBAL(g_freqChange_flag, 0);
GET_SHARED_GLOBAL(g_numUsbChanOut, g_freqChange_sampFreq); /* Misuse of g_freqChange_sampFreq */
/* Reset OUT buffer state */
/* Reset OUT buffer state */
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);
outUnderflow = 1;
if(outOverflow)
{
/* If we were previously in overflow we wont have marked as ready */
/* If we were previously in overflow we wont have marked as ready */
XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_fifo_start+4);
outOverflow = 0;
}
SET_SHARED_GLOBAL(g_freqChange, 0);
ENABLE_INTERRUPTS();
}
@@ -893,34 +893,34 @@ void decouple(chanend c_mix_out,
else if(tmp == SET_DSD_MODE)
{
unsigned dsdMode;
DISABLE_INTERRUPTS();
DISABLE_INTERRUPTS();
/* Clear the buffer as we dont want to send out old PCM samples.. */
SET_SHARED_GLOBAL(g_freqChange_flag, 0);
GET_SHARED_GLOBAL(dsdMode, g_freqChange_sampFreq); /* Misuse of g_freqChange_sampFreq */
/* Reset OUT buffer state */
/* Reset OUT buffer state */
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);
outUnderflow = 1;
if(outOverflow)
{
/* If we were previously in overflow we wont have marked as ready */
/* If we were previously in overflow we wont have marked as ready */
XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_fifo_start+4);
outOverflow = 0;
}
inuint(c_mix_out);
outct(c_mix_out, SET_DSD_MODE);
outuint(c_mix_out, dsdMode);
/* Wait for handshake back */
outuint(c_mix_out, dsdMode);
/* Wait for handshake back */
chkct(c_mix_out, XS1_CT_END);
SET_SHARED_GLOBAL(g_freqChange, 0);
asm("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END));
ENABLE_INTERRUPTS();
}
#endif
@@ -938,17 +938,17 @@ void decouple(chanend c_mix_out,
int aud_from_host_rdptr;
GET_SHARED_GLOBAL(aud_from_host_wrptr, g_aud_from_host_wrptr);
GET_SHARED_GLOBAL(aud_from_host_rdptr, g_aud_from_host_rdptr);
SET_SHARED_GLOBAL(g_aud_from_host_flag, 0);
GET_SHARED_GLOBAL(released_buffer, g_aud_from_host_buffer);
/* Read datalength from buffer */
read_via_xc_ptr(datalength, released_buffer);
/* Ignore bad small packets */
/* Ignore bad small packets */
if ((datalength >= (g_numUsbChanOut * g_slotSize)) && (released_buffer == aud_from_host_wrptr))
{
/* 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;
@@ -959,36 +959,36 @@ void decouple(chanend c_mix_out,
}
SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_wrptr);
}
/* if we have enough space left then send a new buffer pointer
/* if we have enough space left then send a new buffer pointer
* back to the buffer thread */
space_left = aud_from_host_rdptr - aud_from_host_wrptr;
/* Mod and special case */
if(space_left <= 0 && g_aud_from_host_rdptr == aud_from_host_fifo_start)
{
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_USB_AUD_PACKET_SIZE)
{
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);
}
else
{
/* Enter OUT over flow state */
outOverflow = 1;
else
{
/* Enter OUT over flow state */
outOverflow = 1;
#ifdef DEBUG_LEDS
#ifdef DEBUG_LEDS
led(c_led);
#endif
}
}
continue;
}
else if (outOverflow)
else if (outOverflow)
{
int space_left;
int aud_from_host_wrptr;
@@ -996,9 +996,9 @@ void decouple(chanend c_mix_out,
GET_SHARED_GLOBAL(aud_from_host_wrptr, g_aud_from_host_wrptr);
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)
if (space_left <= 0)
space_left += BUFF_SIZE_OUT*4;
if (space_left >= (BUFF_SIZE_OUT*4/2))
if (space_left >= (BUFF_SIZE_OUT*4/2))
{
/* Come out of OUT overflow state */
outOverflow = 0;
@@ -1012,19 +1012,19 @@ void decouple(chanend c_mix_out,
#endif
#ifdef INPUT
{
{
/* 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);
//case inuint_byref(c_buf_in, tmp):
if (tmp)
if (tmp)
{
/* Signals that the IN endpoint has sent data from the passed buffer */
/* Signals that the IN endpoint has sent data from the passed buffer */
/* Reset flag */
SET_SHARED_GLOBAL(g_aud_to_host_flag, 0);
SET_SHARED_GLOBAL(g_aud_to_host_flag, 0);
aud_in_ready = 0;
if (inUnderflow)
if (inUnderflow)
{
int aud_to_host_wrptr;
int aud_to_host_rdptr;
@@ -1038,18 +1038,18 @@ void decouple(chanend c_mix_out,
if (fill_level < 0)
fill_level += BUFF_SIZE_IN*4;
if (fill_level >= IN_BUFFER_PREFILL)
{
if (fill_level >= IN_BUFFER_PREFILL)
{
inUnderflow = 0;
SET_SHARED_GLOBAL(g_aud_to_host_buffer, aud_to_host_rdptr);
}
else
else
{
SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros);
SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros);
}
}
else
}
else
{
/* Not in IN underflow state */
int datalength;
@@ -1068,7 +1068,7 @@ void decouple(chanend c_mix_out,
SET_SHARED_GLOBAL(g_aud_to_host_rdptr, aud_to_host_rdptr);
/* Check for read pointer hitting write pointer - underflow */
if (aud_to_host_rdptr != aud_to_host_wrptr)
if (aud_to_host_rdptr != aud_to_host_wrptr)
{
SET_SHARED_GLOBAL(g_aud_to_host_buffer, aud_to_host_rdptr);
}
@@ -1076,13 +1076,13 @@ void decouple(chanend c_mix_out,
{
inUnderflow = 1;
SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros);
}
}
/* Request to send packet */
}
/* Request to send packet */
{
int p, len;
int p, len;
GET_SHARED_GLOBAL(p, g_aud_to_host_buffer);
asm("ldw %0, %1[0]":"=r"(len):"r"(p));
XUD_SetReady_InPtr(aud_to_host_usb_ep, p+4, len);

View File

@@ -1,9 +1,9 @@
extern unsigned int g_curUsbSpeed;
#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)
*
/* 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
@@ -16,7 +16,7 @@ extern unsigned int g_curUsbSpeed;
*
* Note: Assumes HS (i.e. 8 frames per 1ms)
*
* Examples:
* Examples:
* 44100: min: 5 max: 6
* 48000: min: 5 max: 7
* 96000: min: 11 max: 13
@@ -30,9 +30,9 @@ void GetADCCounts(unsigned samFreq, int *min, int *mid, int *max)
unsigned frameTime;
int usb_speed;
usb_speed = g_curUsbSpeed;
if (usb_speed == XUD_SPEED_HS)
if (usb_speed == XUD_SPEED_HS)
frameTime = 8000;
else
else
frameTime = 1000;
*min = samFreq / frameTime;
@@ -40,7 +40,7 @@ void GetADCCounts(unsigned samFreq, int *min, int *mid, int *max)
*mid = *min;
/* Check for INT(SampFreq/8000) == SampFreq/8000 */
/* Check for INT(SampFreq/8000) == SampFreq/8000 */
if((samFreq % frameTime) == 0)
{
*min -= 1;

View File

@@ -2,23 +2,23 @@
#define __interrupt_h__
#define store_args0(c) \
asm("kentsp 19; stw %0, sp[1]; krestsp 19"::"r"(c));
asm("kentsp 19; stw %0, sp[1]; krestsp 19"::"r"(c));
#define store_args1(c,x) \
asm("kentsp 20; stw %0, sp[1]; stw %1, sp[2]; krestsp 20"::"r"(c),"r"(x));
asm("kentsp 20; stw %0, sp[1]; stw %1, sp[2]; krestsp 20"::"r"(c),"r"(x));
#define store_args2(c,x0,x1) \
asm("kentsp 21; stw %0, sp[1];" \
"stw %1, sp[2];" \
"stw %2, sp[3];" \
" krestsp 21"::"r"(c),"r"(x0),"r"(x1));
" krestsp 21"::"r"(c),"r"(x0),"r"(x1));
#define store_args3(c,x0,x1,x2) \
asm("kentsp 22; stw %0, sp[1];" \
"stw %1, sp[2];" \
"stw %2, sp[3];" \
"stw %3, sp[4];" \
" krestsp 22"::"r"(c),"r"(x0),"r"(x1),"r"(x2));
" krestsp 22"::"r"(c),"r"(x0),"r"(x1),"r"(x2));
#define store_args4(c,x0,x1,x2,x3) \
asm("kentsp 23; stw %4, sp[1];" \
@@ -26,7 +26,7 @@
"stw %1, sp[3];" \
"stw %2, sp[4];" \
"stw %3, sp[5];" \
" krestsp 23"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3));
" krestsp 23"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3));
#define store_args5(c,x0,x1,x2,x3,x4) \
asm("kentsp 24;" \
@@ -36,7 +36,7 @@
"stw %1, sp[4];" \
"stw %2, sp[5];" \
"stw %3, sp[6];" \
" krestsp 24"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4));
" krestsp 24"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4));
#define store_args6(c,x0,x1,x2,x3,x4,x5) \
asm("kentsp 25;" \
@@ -47,7 +47,7 @@
"stw %1, sp[5];" \
"stw %2, sp[6];" \
"stw %3, sp[7];" \
" krestsp 25"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4),"r"(x5));
" krestsp 25"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4),"r"(x5));
#define store_args7(c,x0,x1,x2,x3,x4,x5,x6) \
asm("kentsp 26;" \
@@ -59,7 +59,7 @@
"stw %1, sp[6];" \
"stw %2, sp[7];" \
"stw %3, sp[8];" \
" krestsp 26"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4),"r"(x5),"r"(x6));
" krestsp 26"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4),"r"(x5),"r"(x6));
#define store_args8(c,x0,x1,x2,x3,x4,x5,x6,x7) \
asm("kentsp 27;" \
@@ -72,28 +72,28 @@
"stw %1, sp[7];" \
"stw %2, sp[8];" \
"stw %3, sp[9];" \
" krestsp 27"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4),"r"(x5),"r"(x6),"r"(x7));
" krestsp 27"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4),"r"(x5),"r"(x6),"r"(x7));
#define load_args0(f) \
"ldw r0, sp[1]\n"
"ldw r0, sp[1]\n"
#define load_args1(f)\
"ldw r0, sp[1]\n" \
"ldw r1, sp[2]\n"
"ldw r1, sp[2]\n"
#define load_args2(f)\
"ldw r0, sp[1]\n" \
"ldw r1, sp[2]\n" \
"ldw r2, sp[3]\n"
"ldw r2, sp[3]\n"
#define load_args3(f)\
"ldw r0, sp[1]\n" \
"ldw r1, sp[2]\n" \
"ldw r2, sp[3]\n" \
"ldw r3, sp[4]\n"
"ldw r3, sp[4]\n"
#define load_argsn(f, args) \
".linkset __"#f"_handler_arg0, "#args"-2\n"\
@@ -103,13 +103,13 @@
".linkset __"#f"_handler_arg2, "#args"-0\n"\
"ldw r2, sp[" "__"#f"_handler_arg2" "]\n" \
".linkset __"#f"_handler_arg3, "#args"+1\n"\
"ldw r3, sp[" "__"#f"_handler_arg3" "]\n"
"ldw r3, sp[" "__"#f"_handler_arg3" "]\n"
#define load_args4(f) load_argsn(f,4)
#define load_args5(f) load_argsn(f,5)
#define load_args6(f) load_argsn(f,6)
#define load_args7(f) load_argsn(f,7)
#define load_args8(f) load_argsn(f,8)
#define load_args4(f) load_argsn(f,4)
#define load_args5(f) load_argsn(f,5)
#define load_args6(f) load_argsn(f,6)
#define load_args7(f) load_argsn(f,7)
#define load_args8(f) load_argsn(f,8)
#define save_state(f,args) \
".linkset __"#f"_handler_r0_save, "#args"+12\n" \
@@ -123,7 +123,7 @@
".linkset __"#f"_handler_r11_save, "#args"+11\n" \
"stw r11, sp[" "__"#f"_handler_r11_save" "]\n" \
".linkset __"#f"_handler_lr_save, "#args"+14\n" \
"stw lr, sp[" "__"#f"_handler_lr_save" "]\n"
"stw lr, sp[" "__"#f"_handler_lr_save" "]\n"
#define restore_state(f,args) \
"ldw r0, sp[" "__"#f"_handler_r0_save" "]\n" \
@@ -131,7 +131,7 @@
"ldw r2, sp[" "__"#f"_handler_r2_save" "]\n" \
"ldw r3, sp[" "__"#f"_handler_r3_save" "]\n" \
"ldw r11, sp[" "__"#f"_handler_r11_save" "]\n" \
"ldw lr, sp[" "__"#f"_handler_lr_save" "]\n"
"ldw lr, sp[" "__"#f"_handler_lr_save" "]\n"
#define STRINGIFY0(x) #x

View File

@@ -5,11 +5,11 @@
#pragma select handler
static inline void testct_byref(chanend c, unsigned &isCt)
{
if (testct(c))
if (testct(c))
{
isCt = 1;
}
else
else
{
isCt = 0;
}

View File

@@ -2,13 +2,13 @@
/* TODO Currently complier does not support inline select functions, hense this is in a seperate file to ensure this is not the case */
#pragma select handler
void testct_byrefnot(chanend c, unsigned &isCt)
void testct_byrefnot(chanend c, unsigned &isCt)
{
if (testct(c))
if (testct(c))
{
isCt = 1;
}
else
else
{
isCt = 0;
}

View File

@@ -16,24 +16,24 @@
* \param c_aud_ctl Audio control channel connected to Endpoint0()
* \param p_off_mclk A port that is clocked of the MCLK input (not the MCLK input itself)
*/
void buffer(chanend c_aud_out,
chanend c_aud_in,
void buffer(chanend c_aud_out,
chanend c_aud_in,
chanend c_aud_fb,
#ifdef MIDI
chanend c_midi_from_host,
#ifdef MIDI
chanend c_midi_from_host,
chanend c_midi_to_host,
chanend c_midi,
#endif
#ifdef IAP
chanend c_iap_from_host,
chanend c_iap_from_host,
chanend c_iap_to_host,
chanend c_iap_to_host_int,
chanend c_iap,
#endif
#if defined(SPDIF_RX) || defined(ADAT_RX)
chanend? c_int,
chanend? c_int,
#endif
chanend c_sof,
chanend c_sof,
chanend c_aud_ctl,
in port p_off_mclk
#ifdef HID_CONTROLS

View File

@@ -43,7 +43,7 @@ unsigned g_freqChange = 0;
unsigned char g_intData[8];
#if defined (MIDI) || defined(IAP)
static inline void swap(xc_ptr &a, xc_ptr &b)
static inline void swap(xc_ptr &a, xc_ptr &b)
{
xc_ptr tmp;
tmp = a;
@@ -70,29 +70,29 @@ unsigned char fb_clocks[16];
#define FB_TOLERANCE 0x100
extern unsigned inZeroBuff[];
/**
* Buffers data from audio endpoints
/**
* Buffers data from audio endpoints
* @param c_aud_out chanend for audio from xud
* @param c_aud_in chanend for audio to xud
* @param c_aud_fb chanend for feeback to xud
* @return void
*/
void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud_fb,
#ifdef MIDI
chanend c_midi_from_host,
#ifdef MIDI
chanend c_midi_from_host,
chanend c_midi_to_host,
chanend c_midi,
chanend c_midi,
#endif
#ifdef IAP
chanend c_iap_from_host,
chanend c_iap_to_host,
chanend c_iap_from_host,
chanend c_iap_to_host,
chanend c_iap_to_host_int,
chanend c_iap,
chanend c_iap,
#endif
#if defined(SPDIF_RX) || defined(ADAT_RX)
chanend ?c_int,
chanend ?c_int,
#endif
chanend c_sof,
chanend c_sof,
chanend c_aud_ctl,
in port p_off_mclk
#ifdef HID_CONTROLS
@@ -122,8 +122,8 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
#ifdef HID_CONTROLS
XUD_ep ep_hid = XUD_InitEp(c_hid);
#endif
int tmp;
unsigned u_tmp;
unsigned sampleFreq = 0;
@@ -133,7 +133,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
#ifdef INPUT
unsigned bufferIn = 1;
#endif
#endif
unsigned remnant = 0, cycles;
unsigned sofCount = 0;
unsigned freqChange = 0;
@@ -162,8 +162,8 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
xc_ptr iap_from_host_rdptr;
unsigned char iap_from_host_buffer[MAX_IAP_PACKET_SIZE+4];
unsigned char iap_to_host_buffer[MAX_IAP_PACKET_SIZE+4];
int is_ack_iap;
int is_reset;
unsigned int datum_iap;
@@ -174,20 +174,20 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
xc_ptr p_inZeroBuff = array_to_xc_ptr(inZeroBuff);
#ifdef IAP
XUD_ResetEndpoint(ep_iap_from_host, null);
iap_send_reset(c_iap);
iap_send_reset(c_iap);
#endif
#if defined(SPDIF_RX) || defined(ADAT_RX)
asm("stw %0, dp[int_usb_ep]"::"r"(ep_int));
asm("stw %0, dp[int_usb_ep]"::"r"(ep_int));
#endif
asm("stw %0, dp[aud_from_host_usb_ep]"::"r"(ep_aud_out));
asm("stw %0, dp[aud_to_host_usb_ep]"::"r"(ep_aud_in));
asm("stw %0, dp[buffer_aud_ctl_chan]"::"r"(c_aud_ctl));
asm("stw %0, dp[buffer_aud_ctl_chan]"::"r"(c_aud_ctl));
/* Wait for USB connect then setup our first packet */
/* Wait for USB connect then setup our first packet */
{
int min, mid, max;
int usb_speed = 0;
@@ -200,7 +200,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
GetADCCounts(DEFAULT_FREQ, min, mid, max);
asm("stw %0, dp[g_speed]"::"r"(mid << 16));
if (usb_speed == XUD_SPEED_HS)
if (usb_speed == XUD_SPEED_HS)
mid*=NUM_USB_CHAN_IN*4;
else
mid*=NUM_USB_CHAN_IN_A1*3;
@@ -210,15 +210,15 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
#ifdef FB_TOLERANCE_TEST
expected_fb = ((DEFAULT_FREQ * 0x2000) / 1000);
#endif
}
#ifdef OUTPUT
SET_SHARED_GLOBAL(g_aud_from_host_flag, 1);
SET_SHARED_GLOBAL(g_aud_from_host_flag, 1);
#endif
#ifdef INPUT
SET_SHARED_GLOBAL(g_aud_to_host_flag, 1);
SET_SHARED_GLOBAL(g_aud_to_host_flag, 1);
#endif
(fb_clocks, unsigned[])[0] = 0;
@@ -226,15 +226,15 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
{
int usb_speed;
int x;
asm("ldaw %0, dp[fb_clocks]":"=r"(x));
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
if (usb_speed == XUD_SPEED_HS)
{
if (usb_speed == XUD_SPEED_HS)
{
XUD_SetReady_In(ep_aud_fb, fb_clocks, 4);
}
else
else
{
XUD_SetReady_In(ep_aud_fb, fb_clocks, 3);
}
@@ -260,54 +260,54 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
#if defined(SPDIF_RX) || defined(ADAT_RX)
/* Interrupt EP, send back interrupt data. Note, request made from decouple */
case inuint_byref(c_int, tmp):
{
{
int sent_ok = 0;
XUD_SetData_Inline(ep_int, c_int);
asm("stw %0, dp[g_intFlag]" :: "r" (0) );
asm("stw %0, dp[g_intFlag]" :: "r" (0) );
break;
}
#endif
/* Sample Freq or chan count update from ep 0 */
/* Sample Freq or chan count update from ep 0 */
case testct_byref(c_aud_ctl, u_tmp):
{
if (u_tmp)
if (u_tmp)
{
// is a control token sent by reboot_device
inct(c_aud_ctl);
outct(c_aud_ctl, XS1_CT_END);
while(1) {};
}
else
}
else
{
int min, mid, max;
int usb_speed;
int frameTime;
tmp = inuint(c_aud_ctl);
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
if(tmp == SET_SAMPLE_FREQ)
{
{
sampleFreq = inuint(c_aud_ctl);
/* Don't update things for DFU command.. */
if(sampleFreq != AUDIO_STOP_FOR_DFU)
{
/* Tidy up double buffer, note we can do better than this for 44.1 etc but better
* than sending two packets at old speed! */
if (usb_speed == XUD_SPEED_HS)
/* Tidy up double buffer, note we can do better than this for 44.1 etc but better
* than sending two packets at old speed! */
if (usb_speed == XUD_SPEED_HS)
frameTime = 8000;
else
else
frameTime = 1000;
min = sampleFreq / frameTime;
max = min + 1;
mid = min;
/* Check for INT(SampFreq/8000) == SampFreq/8000 */
/* Check for INT(SampFreq/8000) == SampFreq/8000 */
if((sampleFreq % frameTime) == 0)
{
min -= 1;
@@ -315,26 +315,26 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
#ifdef FB_TOLERANCE_TEST
expected_fb = ((sampleFreq * 0x2000) / frameTime);
#endif
asm("stw %0, dp[g_speed]"::"r"(mid << 16));
if (usb_speed == XUD_SPEED_HS)
if (usb_speed == XUD_SPEED_HS)
mid *= NUM_USB_CHAN_IN*4;
else
else
mid *= NUM_USB_CHAN_IN_A1*3;
asm("stw %0, %1[0]"::"r"(mid),"r"(p_inZeroBuff));
/* Reset FB */
/* Note, Endpoint 0 will hold off host for a sufficient period to allow out feedback
* to stabilise (i.e. sofCount == 128 to fire) */
/* Note, Endpoint 0 will hold off host for a sufficient period to allow out feedback
* to stabilise (i.e. sofCount == 128 to fire) */
sofCount = 0;
clocks = 0;
remnant = 0;
}
}
/* Ideally we want to wait for handshake (and pass back up) here. But we cannot keep this
* thread locked, it must stay responsive to packets/SOFs. So, set a flag and check for
* thread locked, it must stay responsive to packets/SOFs. So, set a flag and check for
* handshake elsewhere */
/* Pass on sample freq change to decouple */
SET_SHARED_GLOBAL0(g_freqChange, SET_SAMPLE_FREQ);
@@ -343,8 +343,8 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
}
else
{
sampleFreq = inuint(c_aud_ctl);
sampleFreq = inuint(c_aud_ctl);
SET_SHARED_GLOBAL0(g_freqChange, tmp); /* Set command */
SET_SHARED_GLOBAL(g_freqChange_sampFreq, sampleFreq); /* Set flag */
SET_SHARED_GLOBAL(g_freqChange_flag, tmp);
@@ -358,14 +358,14 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
/* (previously used 63 instead of 127) */
case inuint_byref(c_sof, u_tmp):
/* NOTE our feedback will be wrong for a couple of SOF's after a SF change due to
* lastClock being incorrect */
/* NOTE our feedback will be wrong for a couple of SOF's after a SF change due to
* lastClock being incorrect */
asm("#sof");
/* Get MCLK count */
asm (" getts %0, res[%1]" : "=r" (u_tmp) : "r" (p_off_mclk));
asm (" getts %0, res[%1]" : "=r" (u_tmp) : "r" (p_off_mclk));
GET_SHARED_GLOBAL(freqChange, g_freqChange);
if(freqChange == SET_SAMPLE_FREQ)
{
@@ -377,34 +377,34 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
unsigned mask = MASK_16_13, usb_speed;
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
if(usb_speed != XUD_SPEED_HS)
mask = MASK_16_10;
/* Number of MCLKS this SOF, approx 125 * 24 (3000), sample by sample rate */
GET_SHARED_GLOBAL(cycles, g_curSamFreqMultiplier);
cycles = ((int)((short)(u_tmp - lastClock))) * cycles;
/* Any odd bits (lower than 16.23) have to be kept seperate */
remnant += cycles & mask;
/* Add 16.13 bits into clock count */
clocks += (cycles & ~mask) + (remnant & ~mask);
remnant += cycles & mask;
/* Add 16.13 bits into clock count */
clocks += (cycles & ~mask) + (remnant & ~mask);
/* and overflow from odd bits. Remove overflow from odd bits. */
remnant &= mask;
/* Store MCLK for next time around... */
lastClock = u_tmp;
remnant &= mask;
/* Reset counts based on SOF counting. Expect 16ms (128 HS SOFs/16 FS SOFS) per feedback poll
* We always count 128 SOFs, so 16ms @ HS, 128ms @ FS */
if(sofCount == 128)
/* Store MCLK for next time around... */
lastClock = u_tmp;
/* Reset counts based on SOF counting. Expect 16ms (128 HS SOFs/16 FS SOFS) per feedback poll
* We always count 128 SOFs, so 16ms @ HS, 128ms @ FS */
if(sofCount == 128)
{
sofCount = 0;
#ifdef FB_TOLERANCE_TEST
if (clocks > (expected_fb - FB_TOLERANCE) &&
clocks < (expected_fb + FB_TOLERANCE))
clocks < (expected_fb + FB_TOLERANCE))
#endif
{
int usb_speed;
@@ -412,24 +412,24 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
//fb_clocks = clocks;
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
if (usb_speed == XUD_SPEED_HS)
{
if (usb_speed == XUD_SPEED_HS)
{
(fb_clocks, unsigned[])[0] = clocks;
}
else
else
{
(fb_clocks, unsigned[])[0] = clocks>>2;
}
}
#ifdef FB_TOLERANCE_TEST
else
else
{
}
#endif
clocks = 0;
}
sofCount++;
}
break;
@@ -441,12 +441,12 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
case XUD_SetData_Select(c_aud_in, ep_aud_in, tmp):
{
/* Inform stream that buffer sent */
SET_SHARED_GLOBAL0(g_aud_to_host_flag, bufferIn+1);
SET_SHARED_GLOBAL0(g_aud_to_host_flag, bufferIn+1);
}
break;
#endif
#ifdef OUTPUT
#ifdef OUTPUT
/* Feedback Pipe */
case XUD_SetData_Select(c_aud_fb, ep_aud_fb, tmp):
{
@@ -455,33 +455,33 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
int x;
asm("#aud fb");
asm("ldaw %0, dp[fb_clocks]":"=r"(x));
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
if (usb_speed == XUD_SPEED_HS)
{
if (usb_speed == XUD_SPEED_HS)
{
XUD_SetReady_In(ep_aud_fb, fb_clocks, 4);
}
else
else
{
XUD_SetReady_In(ep_aud_fb, fb_clocks, 3);
}
}
break;
/* Audio HOST -> DEVICE */
case XUD_GetData_Select(c_aud_out, ep_aud_out, tmp):
{
asm("#h->d aud data");
GET_SHARED_GLOBAL(aud_from_host_buffer, g_aud_from_host_buffer);
write_via_xc_ptr(aud_from_host_buffer, tmp);
/* Sync with decouple thread */
SET_SHARED_GLOBAL0(g_aud_from_host_flag, 1);
}
}
break;
#endif
@@ -491,40 +491,40 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
/* Get buffer data from host - MIDI OUT from host always into a single buffer */
/* Write datalength (tmp) into buffer[0], data stored in buffer[4] onwards */
midi_data_remaining_to_device = tmp;
midi_data_remaining_to_device = tmp;
midi_from_host_rdptr = midi_from_host_buffer;
if (midi_data_remaining_to_device)
if (midi_data_remaining_to_device)
{
read_via_xc_ptr(datum, midi_from_host_rdptr);
outuint(c_midi, datum);
midi_from_host_rdptr += 4;
midi_from_host_rdptr += 4;
midi_data_remaining_to_device -= 4;
}
}
break;
/* MIDI IN to host */
case XUD_SetData_Select(c_midi_to_host, ep_midi_to_host, tmp):
/* MIDI IN to host */
case XUD_SetData_Select(c_midi_to_host, ep_midi_to_host, tmp):
asm("#midi d->h");
/* The buffer has been sent to the host, so we can ack the midi thread */
if (midi_data_collected_from_device != 0)
if (midi_data_collected_from_device != 0)
{
/* Swap the collecting and sending buffer */
swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent);
/* Request to send packet */
XUD_SetReady_InPtr(ep_midi_to_host, midi_to_host_buffer_being_sent, midi_data_collected_from_device);
/* Mark as waiting for host to poll us */
midi_waiting_on_send_to_host = 1;
midi_waiting_on_send_to_host = 1;
/* Reset the collected data count */
midi_data_collected_from_device = 0;
}
else
{
midi_waiting_on_send_to_host = 0;
midi_waiting_on_send_to_host = 0;
}
break;
#endif
@@ -534,7 +534,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
case XUD_GetData_Select(c_iap_from_host, ep_iap_from_host, tmp):
asm("#iap h->d");
if(tmp >= 0)
{
{
iap_data_remaining_to_device = tmp;
if(iap_data_remaining_to_device)
@@ -546,7 +546,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
/* Send out first byte in buffer */
datum_iap = iap_from_host_buffer[0];
outuint(c_iap, datum_iap);
/* Set read ptr to next byte in buffer */
iap_from_host_rdptr = 1;
iap_data_remaining_to_device -= 1;
@@ -559,16 +559,16 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
iap_data_collected_from_device = 0;
}
break;
/* IAP IN to host */
case XUD_SetData_Select(c_iap_to_host, ep_iap_to_host, tmp):
/* IAP IN to host */
case XUD_SetData_Select(c_iap_to_host, ep_iap_to_host, tmp):
asm("#iap d->h");
/* Send out an iAP packet to host, ACK last msg from iAP to let it know we can move on..*/
iap_send_ack(c_iap);
break; /* IAP IN to host */
case XUD_SetData_Select(c_iap_to_host_int, ep_iap_to_host_int, tmp):
break; /* IAP IN to host */
case XUD_SetData_Select(c_iap_to_host_int, ep_iap_to_host_int, tmp):
asm("#iap int d->h");
/* Do nothing.. */
break;
@@ -586,27 +586,27 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
#endif
#ifdef MIDI
/* 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):
if (is_ack)
if (is_ack)
{
/* An ack from the midi/uart thread means it has accepted some data we sent it
* we are okay to send another word */
if (midi_data_remaining_to_device <= 0)
if (midi_data_remaining_to_device <= 0)
{
/* We have read an entire packet - Mark ready to receive another */
XUD_SetReady_OutPtr(ep_midi_from_host, midi_from_host_buffer);
XUD_SetReady_OutPtr(ep_midi_from_host, midi_from_host_buffer);
}
else
else
{
/* Read another word from the fifo and output it to MIDI thread */
read_via_xc_ptr(datum, midi_from_host_rdptr);
outuint(c_midi, datum);
midi_from_host_rdptr += 4;
outuint(c_midi, datum);
midi_from_host_rdptr += 4;
midi_data_remaining_to_device -= 4;
}
}
}
else
else
{
/* The midi/uart thread has sent us some data - handshake back */
midi_send_ack(c_midi);
@@ -618,22 +618,22 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
write_via_xc_ptr(p, datum);
midi_data_collected_from_device += 4;
}
else
else
{
// Too many events from device - drop
}
// Too many events from device - drop
}
// If we are not sending data to the host then initiate it
if (!midi_waiting_on_send_to_host)
if (!midi_waiting_on_send_to_host)
{
swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent);
// Signal other side to swap
XUD_SetReady_InPtr(ep_midi_to_host, midi_to_host_buffer_being_sent, midi_data_collected_from_device);
midi_data_collected_from_device = 0;
midi_waiting_on_send_to_host = 1;
midi_waiting_on_send_to_host = 1;
}
}
}
break;
#endif /* ifdef MIDI */
@@ -641,16 +641,16 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
/* Received word from iap thread - Check for ACK or Data */
case iap_get_ack_or_reset_or_data(c_iap, is_ack_iap, is_reset, datum_iap):
if (is_ack_iap)
if (is_ack_iap)
{
/* An ack from the iap/uart thread means it has accepted some data we sent it
* we are okay to send another word */
if (iap_data_remaining_to_device == 0)
if (iap_data_remaining_to_device == 0)
{
/* We have read an entire packet - Mark ready to receive another */
XUD_SetReady_Out(ep_iap_from_host, iap_from_host_buffer);
}
else
else
{
/* Read another byte from the fifo and output it to iap thread */
datum_iap = iap_from_host_buffer[iap_from_host_rdptr];
@@ -661,13 +661,13 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
}
else
{
if (iap_expected_data_length == 0)
if (iap_expected_data_length == 0)
{
/* Expect a length from iAP core */
iap_send_ack(c_iap);
iap_expected_data_length = datum_iap;
}
else
}
else
{
if (iap_data_collected_from_device < IAP_USB_BUFFER_TO_HOST_SIZE)
{
@@ -675,14 +675,14 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
iap_to_host_buffer[iap_data_collected_from_device] = datum_iap;
iap_data_collected_from_device += 1;
}
else
else
{
// Too many events from device - drop
}
// Too many events from device - drop
}
/* Once we have the whole message, sent it to host */
/* Note we don't ack the last byte yet... */
if (iap_data_collected_from_device == iap_expected_data_length)
if (iap_data_collected_from_device == iap_expected_data_length)
{
XUD_SetReady_In(ep_iap_to_host_int, gc_zero_buffer, 0);
XUD_SetReady_In(ep_iap_to_host, iap_to_host_buffer, iap_data_collected_from_device);

View File

@@ -31,4 +31,4 @@ inline xc_ptr array_to_xc_ptr(const unsigned a[])
#define GET_SHARED_GLOBAL(x, g) asm volatile("ldw %0, dp[" #g "]":"=r"(x)::"memory")
#define SET_SHARED_GLOBAL(g, v) asm volatile("stw %0, dp[" #g "]"::"r"(v):"memory")
#endif
#endif