From a0d9f9239778e84b8f26ae7c843dd5a4293c16ab Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Fri, 21 Oct 2011 14:40:39 +0100 Subject: [PATCH 01/15] Added testmodes to ep0 --- module_usb_aud_shared/endpoint0/endpoint0.xc | 29 +++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/module_usb_aud_shared/endpoint0/endpoint0.xc b/module_usb_aud_shared/endpoint0/endpoint0.xc index 51d3c687..ba897759 100755 --- a/module_usb_aud_shared/endpoint0/endpoint0.xc +++ b/module_usb_aud_shared/endpoint0/endpoint0.xc @@ -133,8 +133,8 @@ static unsigned char strDesc_langIDs[] = DESC_STR_LANGIDS; void VendorAudioRequestsInit(chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl); /* Endpoint 0 function. Handles all requests to the device */ -void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl -) +void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, + chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_usb_test) { unsigned char buffer[512]; SetupPacket sp; @@ -286,7 +286,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, cha cfgDesc_Audio2, sizeof(cfgDesc_Audio2), devQualDesc_Audio1, sizeof(devQualDesc_Audio1), cfgDesc_Audio1, sizeof(cfgDesc_Audio1), - strDescs_Audio2, sp); + strDescs_Audio2, sp, c_usb_test); #else /* Return Audio 2.0 Descriptors */ cfgDesc_Audio2[1] = CONFIGURATION; @@ -297,7 +297,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, cha cfgDesc_Audio2, sizeof(cfgDesc_Audio2), devQualDesc_Null, sizeof(devQualDesc_Null), cfgDesc_Null, sizeof(cfgDesc_Null), - strDescs_Audio2, sp); + strDescs_Audio2, sp, c_usb_test); #endif } else @@ -312,7 +312,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, cha cfgDesc_Audio1, sizeof(cfgDesc_Audio1), devQualDesc_Audio2, sizeof(devQualDesc_Audio2), cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - strDescs_Audio1, sp); + strDescs_Audio1, sp, c_usb_test); #else cfgDesc_Null[1] = CONFIGURATION; @@ -323,7 +323,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, cha cfgDesc_Null, sizeof(cfgDesc_Null), devQualDesc_Audio2, sizeof(devQualDesc_Audio2), cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - strDescs_Audio2, sp); + strDescs_Audio2, sp, c_usb_test); #endif } @@ -343,7 +343,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, cha cfgDesc_Audio2, sizeof(cfgDesc_Audio2), devQualDesc_Audio1, sizeof(devQualDesc_Audio1), cfgDesc_Audio1, sizeof(cfgDesc_Audio1), - strDescs_Audio2, sp); + strDescs_Audio2, sp, c_usb_test); #else /* Return Audio 2.0 Descriptors with Null device as fallback */ cfgDesc_Audio2[1] = CONFIGURATION; @@ -354,7 +354,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, cha cfgDesc_Audio2, sizeof(cfgDesc_Audio2), devQualDesc_Null, sizeof(devQualDesc_Null), cfgDesc_Null, sizeof(cfgDesc_Null), - strDescs_Audio2, sp); + strDescs_Audio2, sp, c_usb_test); #endif } @@ -370,7 +370,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, cha cfgDesc_Audio1, sizeof(cfgDesc_Audio1), devQualDesc_Audio2, sizeof(devQualDesc_Audio2), cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - strDescs_Audio1, sp); + strDescs_Audio1, sp, c_usb_test); #else cfgDesc_Null[1] = CONFIGURATION; cfgDesc_Audio2[1] = OTHER_SPEED_CONFIGURATION; @@ -380,7 +380,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, cha cfgDesc_Null, sizeof(cfgDesc_Null), devQualDesc_Audio2, sizeof(devQualDesc_Audio2), cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - strDescs_Audio2, sp); + strDescs_Audio2, sp, c_usb_test); #endif } @@ -393,7 +393,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, cha DFUcfgDesc, sizeof(DFUcfgDesc), DFUdevQualDesc, sizeof(DFUdevQualDesc), DFUoSpeedCfgDesc, sizeof(DFUoSpeedCfgDesc), - strDescs_Audio2, sp); + strDescs_Audio2, sp, c_usb_test); } #endif @@ -733,9 +733,12 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, cha /* TODO we should not make the assumption that all DFU requests are handled */ retVal = 0; } - /* Check for: Audio interface request - always 0, note we check for DFU first - * Audio endpoint request */ + /* Check for: - Audio CONTROL interface request - always 0, note we check for DFU first + * - Audio STREAMING interface request + * - Audio endpoint request + */ else if(((request == CLASS_INTERFACE_REQUEST) && (interfaceNum == 0)) + || ((request == CLASS_INTERFACE_REQUEST) && (interfaceNum == 1 || interfaceNum == 2)) || (request == CLASS_ENDPOINT_REQUEST && ((interfaceNum == 0x82) || (interfaceNum == 0x01)))) { #endif From 697f68344b091197e8626d863b8f57298b8babe7 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Fri, 21 Oct 2011 14:40:42 +0100 Subject: [PATCH 02/15] Added testmodes to ep0 --- module_usb_aud_shared/endpoint0/endpoint0.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/module_usb_aud_shared/endpoint0/endpoint0.h b/module_usb_aud_shared/endpoint0/endpoint0.h index 3052e609..59314dcb 100644 --- a/module_usb_aud_shared/endpoint0/endpoint0.h +++ b/module_usb_aud_shared/endpoint0/endpoint0.h @@ -13,8 +13,10 @@ * present * \param c_clk_ctl Optional chanend to be connected to the clockgen thread if * present. + * \param c_usb_test Optional chanend to be connected to XUD if test modes required. */ -void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCtrl, chanend ?c_mix_ctl,chanend ?c_clk_ctl +void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCtrl, + chanend ?c_mix_ctl,chanend ?c_clk_ctl, chanend ?c_usb_test #ifdef EP0_THREAD_COMBINED_WITH_SPI , chanend c_spi, chanend c_spi_ss #endif From af0d46800d6eafe46e3eb84a649129876faa968c Mon Sep 17 00:00:00 2001 From: Russell Date: Mon, 21 Nov 2011 11:35:28 +0000 Subject: [PATCH 03/15] Save resources if SPDIF or MIXER not enabled --- module_usb_aud_shared/audio.xc | 12 ++++++++++-- module_usb_aud_shared/endpoint0/audiorequests.xc | 2 ++ module_usb_aud_shared/endpoint0/endpoint0.xc | 4 ++++ module_usb_aud_shared/usb_buffer/decouple.xc | 4 ++++ module_usb_aud_shared/usb_buffer/usb_buffer.xc | 6 ++++++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/module_usb_aud_shared/audio.xc b/module_usb_aud_shared/audio.xc index 42cbd908..811832cc 100755 --- a/module_usb_aud_shared/audio.xc +++ b/module_usb_aud_shared/audio.xc @@ -60,7 +60,7 @@ extern void device_reboot(void); /* I2S delivery thread */ #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) { unsigned sample; #if NUM_USB_CHAN_OUT > 0 @@ -515,7 +515,9 @@ static unsigned dummy_deliver(chanend c_out) { void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config) { +#ifdef SPDIF chan c_spdif_out; +#endif unsigned curSamFreq = DEFAULT_FREQ; unsigned mClk; unsigned divide; @@ -589,7 +591,13 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config) outuint(c_spdif_out, mClk); #endif - curSamFreq = deliver(c_mix_out, c_spdif_out, divide, c_dig_rx); + curSamFreq = deliver(c_mix_out, +#ifdef SPDIF + c_spdif_out, +#else + null, +#endif + divide, c_dig_rx); // Currently no more audio will happen after this point if (curSamFreq == AUDIO_STOP_FOR_DFU) diff --git a/module_usb_aud_shared/endpoint0/audiorequests.xc b/module_usb_aud_shared/endpoint0/audiorequests.xc index f14ecc3d..52ab38e3 100644 --- a/module_usb_aud_shared/endpoint0/audiorequests.xc +++ b/module_usb_aud_shared/endpoint0/audiorequests.xc @@ -35,6 +35,7 @@ extern int volsIn[]; extern unsigned int mutesIn[]; /* Mixer settings */ +#ifdef MIXER extern unsigned char mixer1Crossbar[]; extern short mixer1Weights[]; @@ -48,6 +49,7 @@ extern unsigned char channelMapUsb[NUM_USB_CHAN_IN]; /* Mixer input mapping */ extern unsigned char mixSel[MIX_INPUTS]; +#endif /* Global var for current frequency */ extern unsigned int g_curSamFreq; diff --git a/module_usb_aud_shared/endpoint0/endpoint0.xc b/module_usb_aud_shared/endpoint0/endpoint0.xc index ba897759..393d670e 100755 --- a/module_usb_aud_shared/endpoint0/endpoint0.xc +++ b/module_usb_aud_shared/endpoint0/endpoint0.xc @@ -63,6 +63,7 @@ int volsIn[NUM_USB_CHAN_IN + 1]; unsigned int mutesIn[NUM_USB_CHAN_IN + 1]; //unsigned int multIn[NUM_USB_CHAN_IN + 1]; +#ifdef MIXER unsigned char mixer1Crossbar[18]; short mixer1Weights[18*8]; //#define MAX_MIX_COUNT 8 @@ -75,6 +76,7 @@ unsigned char channelMapAud[NUM_USB_CHAN_OUT]; unsigned char channelMapUsb[NUM_USB_CHAN_IN]; #endif unsigned char mixSel[MIX_INPUTS]; +#endif int min(int x, int y); @@ -161,6 +163,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, mutesIn[i] = 0; } +#ifdef MIXER /* Set up mixer default state */ for (int i = 0; i < 18*8; i++) { mixer1Weights[i] = 0x8001; //-inf @@ -210,6 +213,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, { mixSel[i] = i; } +#endif /* Copy langIDs string desc into string[0] */ /* TODO: Macro? */ diff --git a/module_usb_aud_shared/usb_buffer/decouple.xc b/module_usb_aud_shared/usb_buffer/decouple.xc index 861f2b0f..8c73e1c0 100644 --- a/module_usb_aud_shared/usb_buffer/decouple.xc +++ b/module_usb_aud_shared/usb_buffer/decouple.xc @@ -165,17 +165,21 @@ static inline void swap(xc_ptr &a, xc_ptr &b) } // shared global midi buffering variables +#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 int aud_from_host_usb_ep = 0; int aud_to_host_usb_ep = 0; int int_usb_ep = 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]; +#endif // shared global aud buffering variables diff --git a/module_usb_aud_shared/usb_buffer/usb_buffer.xc b/module_usb_aud_shared/usb_buffer/usb_buffer.xc index 16f8d177..2ef11e36 100644 --- a/module_usb_aud_shared/usb_buffer/usb_buffer.xc +++ b/module_usb_aud_shared/usb_buffer/usb_buffer.xc @@ -85,7 +85,9 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud XUD_ep ep_midi_from_host = XUD_Init_Ep(c_midi_from_host); XUD_ep ep_midi_to_host = XUD_Init_Ep(c_midi_to_host); #endif +#if defined(SPDIF_RX) || defined(ADAT_RX) XUD_ep ep_int = XUD_Init_Ep(c_int); +#endif unsigned datalength; unsigned tmp; @@ -116,7 +118,9 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud set_thread_fast_mode_on(); +#if defined(SPDIF_RX) || defined(ADAT_RX) 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)); @@ -195,6 +199,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud /* Wait for response from XUD and service relevant EP */ select { +#if defined(SPDIF_RX) || defined(ADAT_RX) /* Interrupt EP, send back interrupt data. Note, request made from decouple */ case inuint_byref(c_int, tmp): { @@ -221,6 +226,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud XUD_SetNotReady(ep_int); break; } +#endif /* Sample Freq our chan count update from ep 0 */ case inuint_byref(c_aud_ctl, tmp): From 751713e729e657be0438222181f65605ea203526 Mon Sep 17 00:00:00 2001 From: Russell Date: Mon, 21 Nov 2011 11:54:16 +0000 Subject: [PATCH 04/15] Remove interfaceAlt check --- module_usb_aud_shared/endpoint0/audiorequests.xc | 3 --- 1 file changed, 3 deletions(-) diff --git a/module_usb_aud_shared/endpoint0/audiorequests.xc b/module_usb_aud_shared/endpoint0/audiorequests.xc index 52ab38e3..2cde9948 100644 --- a/module_usb_aud_shared/endpoint0/audiorequests.xc +++ b/module_usb_aud_shared/endpoint0/audiorequests.xc @@ -865,9 +865,6 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, SetupPacket &sp, chanend int num_freqs = 0; int i = 2; - if(interfaceAlt[1] != 0) - printint(interfaceAlt[1]); - #if MAX_FREQ >= 44100 storeFreq(buffer, i, 44100); num_freqs++; From f568790fc36ee548c64f510dc8cd95b1bcb1a0a7 Mon Sep 17 00:00:00 2001 From: Russell Date: Mon, 21 Nov 2011 11:54:33 +0000 Subject: [PATCH 05/15] Reduce midi buffering --- module_usb_aud_shared/usb_buffer/decouple.xc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module_usb_aud_shared/usb_buffer/decouple.xc b/module_usb_aud_shared/usb_buffer/decouple.xc index 8c73e1c0..22071daa 100644 --- a/module_usb_aud_shared/usb_buffer/decouple.xc +++ b/module_usb_aud_shared/usb_buffer/decouple.xc @@ -178,7 +178,7 @@ int int_usb_ep = 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]; +int g_midi_from_host_buffer[MAX_USB_MIDI_PACKET_SIZE/4+4]; #endif // shared global aud buffering variables From 61726fd98b00cbfc9609cb1d2afe48c3a6701a02 Mon Sep 17 00:00:00 2001 From: Russell Date: Mon, 21 Nov 2011 11:54:45 +0000 Subject: [PATCH 06/15] Tidying up in decouple --- module_usb_aud_shared/usb_buffer/decouple.xc | 21 +++++--------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/module_usb_aud_shared/usb_buffer/decouple.xc b/module_usb_aud_shared/usb_buffer/decouple.xc index 22071daa..3377047f 100644 --- a/module_usb_aud_shared/usb_buffer/decouple.xc +++ b/module_usb_aud_shared/usb_buffer/decouple.xc @@ -1033,12 +1033,8 @@ void decouple(chanend c_mix_out, /* Swap the collecting and sending buffer */ swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent); - { - /* Request to send packet */ - int len; - asm("ldw %0, %1[0]":"=r"(len):"r"(midi_to_host_buffer_being_sent)); - XUD_SetReady_In(midi_to_host_usb_ep, 0, midi_to_host_buffer_being_sent+4, len); - } + /* Request to send packet */ + XUD_SetReady_In(midi_to_host_usb_ep, 0, midi_to_host_buffer_being_sent+4, midi_data_collected_from_device); /* Mark as waiting for host to poll us */ midi_waiting_on_send_to_host = 1; @@ -1058,9 +1054,6 @@ void decouple(chanend c_mix_out, if (midi_from_host_flag) { /* The buffer() thread has filled up a buffer */ - int datalength; - int space_left; - /* Reset flag */ SET_SHARED_GLOBAL(g_midi_from_host_flag, 0); @@ -1123,16 +1116,12 @@ void decouple(chanend c_mix_out, if (!midi_waiting_on_send_to_host) { write_via_xc_ptr(midi_to_host_buffer_being_collected, midi_data_collected_from_device); - - midi_data_collected_from_device = 0; + swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent); // Signal other side to swap - { - int len; - asm("ldw %0, %1[0]":"=r"(len):"r"(midi_to_host_buffer_being_sent)); - XUD_SetReady_In(midi_to_host_usb_ep, 0, midi_to_host_buffer_being_sent+4, len); - } + XUD_SetReady_In(midi_to_host_usb_ep, 0, midi_to_host_buffer_being_sent+4, midi_data_collected_from_device); + midi_data_collected_from_device = 0; midi_waiting_on_send_to_host = 1; } } From 4a3c40170f33122b0601303d47ea8a8b23c1f9c8 Mon Sep 17 00:00:00 2001 From: Russell Date: Mon, 21 Nov 2011 12:01:03 +0000 Subject: [PATCH 07/15] Add read write byte functions to xc_ptr --- module_usb_aud_shared/usb_buffer/xc_ptr.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module_usb_aud_shared/usb_buffer/xc_ptr.h b/module_usb_aud_shared/usb_buffer/xc_ptr.h index e2750668..ac6b8b90 100644 --- a/module_usb_aud_shared/usb_buffer/xc_ptr.h +++ b/module_usb_aud_shared/usb_buffer/xc_ptr.h @@ -12,10 +12,16 @@ inline xc_ptr array_to_xc_ptr(unsigned a[]) { #define write_via_xc_ptr(p,x) asm("stw %0, %1[0]"::"r"(x),"r"(p)) #define write_via_xc_ptr_indexed(p,i,x) asm("stw %0, %1[%2]"::"r"(x),"r"(p),"r"(i)) +#define write_byte_via_xc_ptr_indexed(p,i,x) asm("st8 %0, %1[%2]"::"r"(x),"r"(p),"r"(i)) +// No immediate st8 format +#define write_byte_via_xc_ptr(p,x) write_byte_via_xc_ptr_indexed(p, 0, x) #define read_via_xc_ptr(x,p) asm("ldw %0, %1[0]":"=r"(x):"r"(p)); #define read_via_xc_ptr_indexed(x,p,i) asm("ldw %0, %1[%2]":"=r"(x):"r"(p),"r"(i)); +#define read_byte_via_xc_ptr_indexed(x,p,i) asm("ld8u %0, %1[%2]":"=r"(x):"r"(p),"r"(i)); +// No immediate ld8u format +#define read_byte_via_xc_ptr(x,p) read_byte_via_xc_ptr_indexed(x, p, 0) #define GET_SHARED_GLOBAL(x, g) asm("ldw %0, dp[" #g "]":"=r"(x)) #define SET_SHARED_GLOBAL(g, v) asm("stw %0, dp[" #g "]"::"r"(v)) From b683ac963e9ad910f816ebe5347b78a891f65544 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Wed, 7 Dec 2011 12:48:59 +0000 Subject: [PATCH 08/15] Added MIDI_SHIFT --- module_usb_midi/src/usb_midi.xc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/module_usb_midi/src/usb_midi.xc b/module_usb_midi/src/usb_midi.xc index 1c6292d5..9b1d8afe 100644 --- a/module_usb_midi/src/usb_midi.xc +++ b/module_usb_midi/src/usb_midi.xc @@ -6,6 +6,9 @@ #include //#define MIDI_LOOPBACK 1 +#ifndef MIDI_SHIFT +#define MIDI_SHIFT 0 +#endif static unsigned makeSymbol(unsigned data) { // Start and stop bits to the data packet @@ -102,7 +105,7 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, t2 :> rxT; #ifndef MIDI_LOOPBACK - p_midi_out <: 1; // Start with high bit. + p_midi_out <: 1< time; time += bit_time; @@ -218,7 +221,7 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, { time += bit_time; txPT += bit_time; - p_midi_out @ txPT <: (symbol & 1); + p_midi_out @ txPT <: ((symbol & 1)<>= 1; } @@ -305,7 +308,7 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, #ifdef MIDI_LOOPBACK handle_byte_from_uart(c_midi, mips, cable_number, got_next_event, next_event, waiting_for_ack, symbol); #else - p_midi_out <: 1 @ txPT; + p_midi_out <: (1< time; time += bit_time; txPT += bit_time; From 165c184f95b6fbfd06548a41986a7765f80071db Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Tue, 13 Dec 2011 14:41:42 +0000 Subject: [PATCH 09/15] devicedefines.h now included in usb_midi.h --- module_usb_midi/src/usb_midi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/module_usb_midi/src/usb_midi.h b/module_usb_midi/src/usb_midi.h index 3a141eb4..ccc0ee51 100644 --- a/module_usb_midi/src/usb_midi.h +++ b/module_usb_midi/src/usb_midi.h @@ -1,6 +1,7 @@ #ifndef __usb_midi_h__ #define __usb_midi_h__ +#include "devicedefines.h" /** USB MIDI I/O thread. * From 9d1c7754122ee86bcc07d3c5c1047b2cc1bd3c19 Mon Sep 17 00:00:00 2001 From: Russell Date: Thu, 1 Dec 2011 17:04:01 +0000 Subject: [PATCH 10/15] Reduce power requirement and change flags in GetStatus --- module_usb_aud_shared/endpoint0/descriptors_2.h | 4 ++-- module_usb_aud_shared/endpoint0/endpoint0.xc | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/module_usb_aud_shared/endpoint0/descriptors_2.h b/module_usb_aud_shared/endpoint0/descriptors_2.h index c1b86fee..0931cb03 100644 --- a/module_usb_aud_shared/endpoint0/descriptors_2.h +++ b/module_usb_aud_shared/endpoint0/descriptors_2.h @@ -233,7 +233,7 @@ unsigned char cfgDesc_Audio2[] = 0x00, /* 6 iConfiguration */ #ifdef SELF_POWERED 192, /* 7 bmAttributes */ - 5, /* 8 bMaxPower */ + 0, /* 8 bMaxPower */ #else 128, /* 7 bmAttributes */ 250, /* 8 bMaxPower */ @@ -1299,7 +1299,7 @@ unsigned char cfgDesc_Audio1[] = 0x00, /* Unused */ #ifdef SELF_POWERED 192, /* 7 bmAttributes */ - 5, /* 8 bMaxPower */ + 0, /* 8 bMaxPower */ #else 128, /* 7 bmAttributes */ 250, /* 8 bMaxPower */ diff --git a/module_usb_aud_shared/endpoint0/endpoint0.xc b/module_usb_aud_shared/endpoint0/endpoint0.xc index 393d670e..9343e7a6 100755 --- a/module_usb_aud_shared/endpoint0/endpoint0.xc +++ b/module_usb_aud_shared/endpoint0/endpoint0.xc @@ -584,7 +584,11 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, /* Get Status request */ case GET_STATUS: +#ifdef SELF_POWERED + buffer[0] = 1; // self powered +#else buffer[0] = 0; // bus powered +#endif buffer[1] = 0; // remote wakeup not supported retVal = XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength); From 9bcc2cf2b039a37e1495c6fc24dfed633b8058e2 Mon Sep 17 00:00:00 2001 From: Russell Date: Wed, 14 Dec 2011 11:26:14 +0000 Subject: [PATCH 11/15] Fix null config descriptor in SELF_POWERED mode. --- module_usb_aud_shared/endpoint0/descriptors_2.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/module_usb_aud_shared/endpoint0/descriptors_2.h b/module_usb_aud_shared/endpoint0/descriptors_2.h index 0931cb03..6048bbec 100644 --- a/module_usb_aud_shared/endpoint0/descriptors_2.h +++ b/module_usb_aud_shared/endpoint0/descriptors_2.h @@ -1231,11 +1231,12 @@ unsigned char cfgDesc_Null[] = 0x01, /* 5 bConfigurationValue */ 0x00, /* 6 iConfiguration */ #ifdef SELF_POWERED - 192, /* 7 bmAttributes */ + 192, /* 7 bmAttributes */ + 0, /* 8 bMaxPower */ #else 128, -#endif 250, /* 8 bMaxPower */ +#endif 0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */ 0x04, /* 1 bDescriptorType : INTERFACE descriptor. (field size 1 bytes) */ From 6bf8d1c47557fe93b725738972e2d60244d62266 Mon Sep 17 00:00:00 2001 From: Russell Date: Fri, 16 Dec 2011 12:26:17 +0000 Subject: [PATCH 12/15] Refactor usb midi --- module_usb_midi/src/queue.c | 84 ++++++++++ module_usb_midi/src/queue.h | 25 +++ module_usb_midi/src/usb_midi.h | 4 +- module_usb_midi/src/usb_midi.xc | 280 +++++++++++++------------------- 4 files changed, 227 insertions(+), 166 deletions(-) create mode 100644 module_usb_midi/src/queue.c create mode 100644 module_usb_midi/src/queue.h diff --git a/module_usb_midi/src/queue.c b/module_usb_midi/src/queue.c new file mode 100644 index 00000000..1852b466 --- /dev/null +++ b/module_usb_midi/src/queue.c @@ -0,0 +1,84 @@ +#include +#include "queue.h" + +// Queue implementation +// Offers no protection against adding when full or dequeueing when empty. +// Uses read and write counts for pointers to distinguish full and empty cases. +// Works from c and xc +// Must allocate the memory outside of this and pass it in to init_queue so can statically allocate +// Must work for different element sizes + +// This presumes that the xc compiler will not re-use the mem passed to init_queue +void init_queue(queue *q, unsigned char arr[], int size, int element_size) { + q->rdptr = 0; + q->wrptr = 0; + q->data = (uintptr_t)arr; + q->size = size; // in items, presume that size is power of two + q->element_size = element_size; // The size of each element in bytes + q->mask = size - 1; +} + +extern inline void enqueue(queue *q, unsigned value) { + switch (q->element_size) { + case 4: + ((unsigned *)q->data)[q->wrptr & q->mask] = value; + break; + case 1: + ((unsigned char *)q->data)[q->wrptr & q->mask] = (unsigned char)value; + break; + default: + break; + } + q->wrptr++; +} + +extern inline unsigned dequeue(queue *q) { + unsigned retval; + switch (q->element_size) { + case 4: + retval = ((unsigned *)q->data)[q->rdptr & q->mask]; + break; + case 1: + retval = ((unsigned char *)q->data)[q->rdptr & q->mask]; + break; + default: + break; + } + q->rdptr++; + return retval; +} + +extern inline int isempty(queue *q) { + return (q->rdptr == q->wrptr); +} + +extern inline int isfull(queue *q) { + return ((q->wrptr - q->rdptr) == q->size); +} + +extern inline int items(queue *q) { + int items = q->wrptr - q->rdptr; + return items; +} + +// How to calculate size? Could make it a function call or leave it as a variable within the struct +extern inline int space(queue *q) { + return q->size - items(q); +} + +void dump(queue *q) { + for (int i = q->rdptr; i != q->wrptr; i++) { + switch (q->element_size) { + case 4: + printf("a[%d] = %d\n", i & q->mask, ((unsigned *)q->data)[i & q->mask]); + break; + case 1: + printf("a[%d] = %d\n", i & q->mask, ((unsigned char *)q->data)[i & q->mask]); + break; + default: + break; + } + } +} + + diff --git a/module_usb_midi/src/queue.h b/module_usb_midi/src/queue.h new file mode 100644 index 00000000..1e04c8d0 --- /dev/null +++ b/module_usb_midi/src/queue.h @@ -0,0 +1,25 @@ +#ifndef QUEUE_H +#define QUEUE_H + +#include +#include + +typedef struct queue { + uintptr_t data; + int rdptr; // Using absolute indices which count reads and writes so this needs to be considered when accessing. + int wrptr; + int size; + int element_size; + int mask; +} queue; + +void init_queue(REFERENCE_PARAM(queue, q), unsigned char arr[], int size, int element_size); +void enqueue(REFERENCE_PARAM(queue, q), unsigned value); +unsigned dequeue(REFERENCE_PARAM(queue, q)); +int isempty(REFERENCE_PARAM(queue, q)); +int isfull(REFERENCE_PARAM(queue, q)); +int items(REFERENCE_PARAM(queue, q)); +int space(REFERENCE_PARAM(queue, q)); +void dump(REFERENCE_PARAM(queue, q)); + +#endif // QUEUE_H diff --git a/module_usb_midi/src/usb_midi.h b/module_usb_midi/src/usb_midi.h index ccc0ee51..35bd4a9b 100644 --- a/module_usb_midi/src/usb_midi.h +++ b/module_usb_midi/src/usb_midi.h @@ -40,7 +40,7 @@ void midi_get_ack_or_data(chanend c, int &is_ack, unsigned int &datum); INLINE void midi_get_ack_or_data(chanend c, int &is_ack, unsigned int &datum) { if (testct(c)) { is_ack = 1; - (void) inct(c); + (void) inct(c); // read 1-bytes control token (void) inuchar(c); (void) inuchar(c); (void) inuchar(c); @@ -52,7 +52,6 @@ INLINE void midi_get_ack_or_data(chanend c, int &is_ack, unsigned int &datum) { } #endif - INLINE void midi_send_ack(chanend c) { outct(c, MIDI_ACK); outuchar(c, 0); @@ -60,5 +59,4 @@ INLINE void midi_send_ack(chanend c) { outuchar(c, 0); } - #endif // __usb_midi_h__ diff --git a/module_usb_midi/src/usb_midi.xc b/module_usb_midi/src/usb_midi.xc index 9b1d8afe..124c0078 100644 --- a/module_usb_midi/src/usb_midi.xc +++ b/module_usb_midi/src/usb_midi.xc @@ -1,9 +1,11 @@ #include #include +#include +#include #include "usb_midi.h" #include "midiinparse.h" #include "midioutparse.h" -#include +#include "queue.h" //#define MIDI_LOOPBACK 1 #ifndef MIDI_SHIFT @@ -12,6 +14,7 @@ static unsigned makeSymbol(unsigned data) { // Start and stop bits to the data packet + // like 10'b1dddddddd0 return (data << 1) | 0x200; } @@ -20,21 +23,22 @@ static unsigned makeSymbol(unsigned data) { static unsigned bit_time = XS1_TIMER_MHZ * 1000000 / (unsigned) RATE; static unsigned bit_time_2 = (XS1_TIMER_MHZ * 1000000 / (unsigned) RATE) / 2; -int mr_count = 0; -int th_count = 0; +// For debugging +int mr_count = 0; // MIDI received (from HOST) +int th_count = 0; // MIDI sent (To Host) #ifdef MIDI_LOOPBACK -static inline void handle_byte_from_uart(chanend c_midi, struct midi_in_parse_state &mips, int cable_number, +static inline void handle_byte_from_uart(chanend c_midi, struct midi_in_parse_state &mips, int cable_number, int &got_next_event, int &next_event, int &waiting_for_ack, int byte) { int valid; unsigned event; - {valid, event} = midi_in_parse(mips, cable_number, byte); + {valid, event} = midi_in_parse(mips, cable_number, byte); if (valid && !got_next_event) { // data to send to host if (!waiting_for_ack) { - // send data - event = byterev(event); + // send data + event = byterev(event); outuint(c_midi, event); th_count++; waiting_for_ack = 1; @@ -51,71 +55,68 @@ static inline void handle_byte_from_uart(chanend c_midi, struct midi_in_parse_ } #endif -int uout_count = 0; -int uin_count = 0; +int uout_count = 0; // UART bytes out +int uin_count = 0; // UART bytes in -void usb_midi(in port ?p_midi_in, out port ?p_midi_out, +void usb_midi(in port ?p_midi_in, out port ?p_midi_out, clock ?clk_midi, chanend c_midi, - unsigned cable_number) -{ - int is_ack; - unsigned int datum; - unsigned symbol = 0x0; - unsigned outputting = 0; - unsigned time; + unsigned cable_number +) + { + unsigned symbol = 0x0; // Symbol in progress of being sent out + unsigned isTX = 0; // Guard when outputting data + unsigned txT; // Timer value used for outputting //unsigned inputPortState, newInputPortState; int waiting_for_ack = 0; // Receiver unsigned rxByte; int rxI; int rxT; - int isRX = 0; + int isRX = 0; // Guard when receiving data timer t; timer t2; - // these two vars make a one place buffer for data going out to host - int got_next_event = 0; - int next_event; + // One place buffer for data going out to host + queue midi_to_host_fifo; + unsigned char midi_to_host_fifo_arr[4]; // Used for 32bit USB MIDI events + unsigned outputting_symbol, outputted_symbol; struct midi_in_parse_state mips; // the symbol fifo (to go out of uart) - unsigned symbol_fifo[USB_MIDI_DEVICE_OUT_FIFO_SIZE]; - int rdptr = 0; - int wrptr = 0; + queue symbol_fifo; + unsigned char symbol_fifo_arr[USB_MIDI_DEVICE_OUT_FIFO_SIZE * 4]; // Used for 32bit USB MIDI events + unsigned rxPT, txPT; int midi_from_host_overflow = 0; - int space_left; + //configure_clock_rate(clk_midi, 100, 1); + init_queue(symbol_fifo, symbol_fifo_arr, USB_MIDI_DEVICE_OUT_FIFO_SIZE, 4); + init_queue(midi_to_host_fifo, midi_to_host_fifo_arr, 1, 4); - //configure_clock_rate(clk_midi, 100, 1); - - configure_out_port_no_ready(p_midi_out, clk_midi, 1); - configure_in_port(p_midi_in, clk_midi); + configure_out_port_no_ready(p_midi_out, clk_midi, 1); + configure_in_port(p_midi_in, clk_midi); - start_clock(clk_midi); - start_port(p_midi_out); - start_port(p_midi_in); + start_clock(clk_midi); + start_port(p_midi_out); + start_port(p_midi_in); - reset_midi_state(mips); + reset_midi_state(mips); - t :> time; + t :> txT; t2 :> rxT; #ifndef MIDI_LOOPBACK - p_midi_out <: 1< p_midi_in when pinseq(0xE) :> void @ rxPT: @@ -124,197 +125,150 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, #endif isRX = 1; t2 :> rxT; - rxT += (bit_time + bit_time_2); + rxT += (bit_time + bit_time_2); rxPT += (bit_time + bit_time_2); // absorb start bit and set to halfway through the next bit rxI = 0; asm("setc res[%0],1"::"r"(p_midi_in)); asm("setpt res[%0],%1"::"r"(p_midi_in),"r"(rxPT)); - break; + break; // Input to read the remaining bits case isRX => t2 when timerafter(rxT) :> int _ : - if (rxI++ < 8) - { - unsigned bit; - p_midi_in :> bit; + { + unsigned bit; + p_midi_in :> bit; + if (rxI++ < 8) { + // shift in bits into the high end of a word rxByte = (bit << 31) | (rxByte >> 1); rxT += bit_time; rxPT += bit_time; - asm("setpt res[%0],%1"::"r"(p_midi_in),"r"(rxPT)); - } - else - { - unsigned bit; + asm("setpt res[%0],%1"::"r"(p_midi_in),"r"(rxPT)); + } else { // rcv and check stop bit - p_midi_in :> bit; - if ((bit & 0x1) == 1) - { + if ((bit & 0x1) == 1) { unsigned valid = 0; unsigned event = 0; uin_count++; rxByte >>= 24; // if (rxByte != outputted_symbol) { + // // Loopback check // printhexln(rxByte); // printhexln(outputted_symbol); // } {valid, event} = midi_in_parse(mips, cable_number, rxByte); - if (valid && !got_next_event) { - event = byterev(event); + if (valid && isempty(midi_to_host_fifo)) { + event = byterev(event); // data to send to host - add to fifo if (!waiting_for_ack) { - // send data - // printstr("uart->decouple: "); + // send data + // printstr("uart->decouple: "); outuint(c_midi, event); waiting_for_ack = 1; th_count++; + } else { + enqueue(midi_to_host_fifo, event); } - else { - next_event = event; - got_next_event = 1; - } - } - else if (valid) { + } else if (valid) { // printstr("g"); } - - } + } isRX = 0; } break; - - // Output - // If outputting then feed the bits out one at a time - // until symbol is zero expect pattern like 10'b1dddddddd0 - // This code will leave the output high afterwards due to the stop bit added with makeSymbol - case outputting => t when timerafter(time) :> int _: - if (symbol == 0) - { - uout_count++; - outputted_symbol = outputting_symbol; - // have we got another symbol to send to uart? - if (rdptr != wrptr) { - outputting_symbol = symbol_fifo[rdptr]; - symbol = makeSymbol(symbol_fifo[rdptr]); - rdptr++; - if (rdptr > USB_MIDI_DEVICE_OUT_FIFO_SIZE - 1) - rdptr = 0; + } - space_left = rdptr - wrptr; - if (space_left < 0) - space_left += USB_MIDI_DEVICE_OUT_FIFO_SIZE; + // Output + // If isTX then feed the bits out one at a time + // until symbol is zero expect pattern like 10'b1dddddddd0 + // This code will leave the output high afterwards due to the stop bit added with makeSymbol + case isTX => t when timerafter(txT) :> int _: + if (symbol == 0) { + // Got something to output but not mid-symbol. + // Start sending symbol. + // This case is reached when a symbol has been received from the host but not started AND + // When it has just finished sending a symbol - if (space_left > 3 && midi_from_host_overflow) { - midi_from_host_overflow = 0; - midi_send_ack(c_midi); - } + // Take from FIFO + outputting_symbol = dequeue(symbol_fifo); + symbol = makeSymbol(outputting_symbol); - p_midi_out <: (1< time; - time += bit_time; - txPT += bit_time; + if (space(symbol_fifo) > 3 && midi_from_host_overflow) { + midi_from_host_overflow = 0; + midi_send_ack(c_midi); } - else - outputting = 0; - } - else - { - time += bit_time; + + p_midi_out <: (1< txT; + txT += bit_time; + txPT += bit_time; + isTX = 1; + } else { + // Mid-symbol + txT += bit_time; // Should this be after the output otherwise be double the length of the high before the start bit txPT += bit_time; p_midi_out @ txPT <: ((symbol & 1)<>= 1; - } - break; + if (symbol == 0) { + // Finished sending byte + uout_count++; + outputted_symbol = outputting_symbol; + if (isempty(symbol_fifo)) { // FIFO empty + isTX = 0; + } + } + } + break; #endif case midi_get_ack_or_data(c_midi, is_ack, datum): if (is_ack) { // have we got more data to send //printstr("ack\n"); - if (got_next_event) { + if (!isempty(midi_to_host_fifo)) { //printstr("uart->decouple\n"); - outuint(c_midi, next_event); + outuint(c_midi, dequeue(midi_to_host_fifo)); th_count++; - got_next_event = 0; - } - else { + } else { waiting_for_ack = 0; - } - } - else { - int event; + } + } else { unsigned midi[3]; unsigned size; - int valid; // received data from host - event = byterev(datum); + int event = byterev(datum); mr_count++; #ifdef MIDI_LOOPBACK - if (!got_next_event) { + if (isempty(midi_to_host_fifo)) { // data to send to host if (!waiting_for_ack) { - // send data - event = byterev(event); + // send data + event = byterev(event); outuint(c_midi, event); th_count++; waiting_for_ack = 1; - } - else { + } else { event = byterev(event); - next_event = event; - got_next_event = 1; + enqueue(midi_to_host_fifo, event); } } #else {midi[0], midi[1], midi[2], size} = midi_out_parse(event); for (int i = 0; i != size; i++) { // add symbol to fifo - unsigned sym = midi[i]; - int new_wrptr = wrptr + 1; - - if (new_wrptr > USB_MIDI_DEVICE_OUT_FIFO_SIZE - 1) { - new_wrptr = 0; - } - - symbol_fifo[wrptr] = sym; - wrptr = new_wrptr; + enqueue(symbol_fifo, midi[i]); } - - space_left = rdptr - wrptr; - if (space_left < 0) - space_left += USB_MIDI_DEVICE_OUT_FIFO_SIZE; - - if (space_left > 3) { + if (space(symbol_fifo) > 3) { midi_send_ack(c_midi); - } - else { + } else { midi_from_host_overflow = 1; } - - if (wrptr != rdptr && !outputting) { - outputting_symbol = symbol_fifo[rdptr]; - symbol = makeSymbol(symbol_fifo[rdptr]); - rdptr++; - if (rdptr > USB_MIDI_DEVICE_OUT_FIFO_SIZE - 1) - rdptr = 0; - - if (space_left > 2 && midi_from_host_overflow) { - midi_from_host_overflow = 0; - midi_send_ack(c_midi); - } - -#ifdef MIDI_LOOPBACK - handle_byte_from_uart(c_midi, mips, cable_number, got_next_event, next_event, waiting_for_ack, symbol); -#else - p_midi_out <: (1< time; - time += bit_time; - txPT += bit_time; - outputting = 1; -#endif - + // Drop through to the isTX guarded case + if (!isTX) { + t :> txT; // Should be enough to trigger the other case + isTX = 1; } #endif } From 639f8865262c21caeb719f1cc4bd553f32375d48 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Tue, 21 Feb 2012 12:01:17 +0000 Subject: [PATCH 13/15] Config channel added to codec config calls --- module_usb_aud_shared/audio.xc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module_usb_aud_shared/audio.xc b/module_usb_aud_shared/audio.xc index 811832cc..c261f73e 100755 --- a/module_usb_aud_shared/audio.xc +++ b/module_usb_aud_shared/audio.xc @@ -528,7 +528,7 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config) #endif /* Initialise master clock generation */ - ClockingInit(); + ClockingInit(c_config); /* Perform required CODEC/ADC/DAC initialisation */ CodecInit(c_config); @@ -550,7 +550,7 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config) divide = mClk / ( curSamFreq * 64 ); /* Configure clocking for required master clock */ - ClockingConfig(mClk); + ClockingConfig(mClk, c_config); if(!firstRun) { From bd2c299a5cca8d87528b78da9198775b4868cddd Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Tue, 21 Feb 2012 14:05:55 +0000 Subject: [PATCH 14/15] Added optional channelend argument --- module_usb_aud_shared/clocking/clocking.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/module_usb_aud_shared/clocking/clocking.h b/module_usb_aud_shared/clocking/clocking.h index 88fc786b..5d7d8f9e 100644 --- a/module_usb_aud_shared/clocking/clocking.h +++ b/module_usb_aud_shared/clocking/clocking.h @@ -4,11 +4,15 @@ /* Functions that handle master clock generation. These need modifying for an existing design */ -/* Any initialisation required for master clock generation - run once at start up */ -void ClockingInit(void); +/* Any initialisation required for master clock generation - run once at start up + * An optional chanend is passed for communcation to another thread e.g. a I2C server thread + */ +void ClockingInit(chanend ?c); -/* Configuration for a specific master clock frequency - run every sample frequency change */ -void ClockingConfig(unsigned mClkFreq); +/* Configuration for a specific master clock frequency - run every sample frequency change +* An optional chanend is passed for communcation to another thread e.g. a I2C server thread + */ +void ClockingConfig(unsigned mClkFreq, chanend ?c); /** Clock generation and digital audio I/O handling. From 425ffc90b1ec6c9b05951a478c34c53d92c01b09 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Tue, 21 Feb 2012 14:10:35 +0000 Subject: [PATCH 15/15] Added optional channelend argument --- module_usb_aud_shared/pll/pll.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module_usb_aud_shared/pll/pll.h b/module_usb_aud_shared/pll/pll.h index d79ca14f..af761d72 100644 --- a/module_usb_aud_shared/pll/pll.h +++ b/module_usb_aud_shared/pll/pll.h @@ -1,4 +1,4 @@ -void PllInit(void); +void PllInit(chanend ?c); -void PllMult(unsigned mult); +void PllMult(unsigned mult, chanend ?c);