Merge branch '6V3_DEV'

This commit is contained in:
Ross Owen
2014-01-13 16:28:04 +00:00
38 changed files with 1068 additions and 2131 deletions

172
.cproject
View File

@@ -1,172 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
<cproject>
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.xmos.cdt.toolchain.30841826">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.xmos.cdt.toolchain.30841826" moduleId="org.eclipse.cdt.core.settings" name="XMOS Compiler Collection (xcc)">
<externalSettings/>
<extensions>
<extension id="com.xmos.cdt.core.XEBinaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.xmos.cdt.core.XMapErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="sc_usb_audio" buildProperties="" description="" id="com.xmos.cdt.toolchain.30841826" name="XMOS Compiler Collection (xcc)" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="com.xmos.cdt.toolchain.30841826.1961785845" name="/" resourcePath="">
<toolChain id="com.xmos.cdt.toolchain.331533569" name="com.xmos.cdt.toolchain" superClass="com.xmos.cdt.toolchain">
<targetPlatform archList="all" binaryParser="com.xmos.cdt.core.XEBinaryParser" id="com.xmos.cdt.core.platform.312514423" isAbstract="false" osList="linux,win32,macosx" superClass="com.xmos.cdt.core.platform"/>
<builder arguments="-f Makefile" buildPath="${workspace_loc:/sc_usb_audio}" command="xmake" id="com.xmos.cdt.builder.base.484433574" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="com.xmos.cdt.builder.base"/>
<tool id="com.xmos.cdt.linker.base.564215645" name="XMOS Mapper" superClass="com.xmos.cdt.linker.base">
<inputType id="com.xmos.cdt.linker.input.xm.71127389" name="XM File"/>
<inputType id="com.xmos.cdt.linker.input.1104586842" superClass="com.xmos.cdt.linker.input">
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="com.xmos.cdt.linker.xnInput.293377365" name="XN File" superClass="com.xmos.cdt.linker.xnInput"/>
<inputType id="com.xmos.cdt.linker.xtaInput.621753651" name="XTA input" superClass="com.xmos.cdt.linker.xtaInput"/>
</tool>
<tool id="com.xmos.cdt.c.compiler.base.372649012" name="XMOS C Compiler" superClass="com.xmos.cdt.c.compiler.base">
<inputType id="com.xmos.cdt.c.compiler.input.1533247653" superClass="com.xmos.cdt.c.compiler.input"/>
<inputType id="com.xmos.cdt.c.compilerXNInput.818861648" name="XN File" superClass="com.xmos.cdt.c.compilerXNInput"/>
</tool>
<tool id="com.xmos.cdt.cpp.compiler.base.1161396055" name="XMOS C++ Compiler" superClass="com.xmos.cdt.cpp.compiler.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1553804963" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="com.xmos.cdt.xc.compiler.base.86146009" name="XMOS XC Compiler" superClass="com.xmos.cdt.xc.compiler.base">
<inputType id="com.xmos.cdt.xc.compiler.input.679575792" name="XC Sources" superClass="com.xmos.cdt.xc.compiler.input"/>
<inputType id="com.xmos.cdt.core.xcCompilerXNInput.258588578" name="XN File" superClass="com.xmos.cdt.core.xcCompilerXNInput"/>
</tool>
<tool id="com.xmos.cdt.core.assembler.base.839004633" name="XMOS Assembler" superClass="com.xmos.cdt.core.assembler.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1797700444" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
<inputType id="com.xmos.cdt.core.asmXNInput.1869517701" name="XN File" superClass="com.xmos.cdt.core.asmXNInput"/>
</tool>
<tool id="com.xmos.cdt.archiver.base.730151905" name="Archiver" superClass="com.xmos.cdt.archiver.base"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
<profile id="com.xmos.cdt.core.XCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -v ${plugin_state_location}/specs.xc" command="xcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>xmake</buildCommand>
<buildArguments>-f .makefile</buildArguments>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="app_uart_test.all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>xmake</buildCommand>
<buildArguments>-f Makefile</buildArguments>
<buildTarget>app_uart_test.all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="sc_usb_audio.null.306906532" name="sc_usb_audio"/>
</storageModule>
</cproject>

View File

@@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>sc_usb_audio</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
<dictionary>
<key>?name?</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value>-f Makefile</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
<value>xmake</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildLocation</key>
<value>${workspace_loc:/sc_usb_audio}</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>false</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.core.cnature</nature>
</natures>
</projectDescription>

14
CHANGELOG.rst Normal file
View File

@@ -0,0 +1,14 @@
sc_usb_audio Change Log
=======================
6.3.1
-----
* see sw_usb_audio for changelog
6.3.0
-----
* see sw_usb_audio for changelog

View File

@@ -1,3 +1,11 @@
module_dfu
==========
:scope: General Use
:description: module_dfu
:keywords: DFU
:boards: XMOS USB Audio Reference Designes
Code providing firmware upgrade over USB. Code providing firmware upgrade over USB.
./host provides an example of a host application for DFU. This is written and tested for OSX. LibUSB is used to aid cross-platform porting. ./host provides an example of a host application for DFU. This is written and tested for OSX. LibUSB is used to aid cross-platform porting.

View File

@@ -3,11 +3,11 @@
#include "devicedefines.h" #include "devicedefines.h"
#include "xud.h" #include "xud.h"
#ifdef ARCH_G //#ifdef ARCH_G
#include "XUD_USB_Defines.h" //#include "XUD_USB_Defines.h"
#else //#else
#include "usb.h" #include "usb.h"
#endif //#endif
#include "dfu_types.h" #include "dfu_types.h"
#include "flash_interface.h" #include "flash_interface.h"
@@ -357,7 +357,7 @@ int DFUReportResetState(chanend ?c_user_cmd)
return inDFU; return inDFU;
} }
int XMOS_DFU_RevertFactory(chanend ?c_user_cmd) static int XMOS_DFU_RevertFactory(chanend ?c_user_cmd)
{ {
unsigned s = 0; unsigned s = 0;
@@ -371,7 +371,7 @@ int XMOS_DFU_RevertFactory(chanend ?c_user_cmd)
return 0; return 0;
} }
int XMOS_DFU_SelectImage(unsigned int index, chanend ?c_user_cmd) static int XMOS_DFU_SelectImage(unsigned int index, chanend ?c_user_cmd)
{ {
// Select the image index for firmware update // Select the image index for firmware update
// Currently not used or implemented // Currently not used or implemented
@@ -379,12 +379,12 @@ int XMOS_DFU_SelectImage(unsigned int index, chanend ?c_user_cmd)
} }
int XMOS_DFU_SaveState() static int XMOS_DFU_SaveState()
{ {
return 0; return 0;
} }
int XMOS_DFU_LoadState() static int XMOS_DFU_LoadState()
{ {
return 0; return 0;
} }
@@ -400,11 +400,7 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, ch
{ {
// Host to device // Host to device
if (sp.wLength) if (sp.wLength)
#ifdef ARCH_G
data_buffer_len = XUD_GetBuffer_(ep0_out, 0, (data_buffer, unsigned char[]));
#else
data_buffer_len = XUD_GetBuffer(ep0_out, (data_buffer, unsigned char[])); data_buffer_len = XUD_GetBuffer(ep0_out, (data_buffer, unsigned char[]));
#endif
} }
// Map Standard DFU commands onto device level firmware upgrade mechanism // Map Standard DFU commands onto device level firmware upgrade mechanism

View File

@@ -0,0 +1,14 @@
# You can set flags specifically for your module by using the MODULE_XCC_FLAGS
# variable. So the following
#
# MODULE_XCC_FLAGS = $(XCC_FLAGS) -O3
#
# specifies that everything in the modules should have the application
# build flags with -O3 appended (so the files will build at
# optimization level -O3).
#
# You can also set MODULE_XCC_C_FLAGS, MODULE_XCC_XC_FLAGS etc..
MODULE_XCC_XC_FLAGS = $(XCC_XC_FLAGS)
DEPENDENT_MODULES = module_xassert

View File

@@ -0,0 +1 @@
One line module description.

65
module_queue/src/queue.h Normal file
View File

@@ -0,0 +1,65 @@
#ifndef QUEUE_H_
#define QUEUE_H_
#include <xassert.h>
typedef struct queue_t {
/// Read index.
unsigned rdptr;
/// Write index.
unsigned wrptr;
unsigned size;
unsigned mask;
} queue_t;
inline int is_power_of_2(unsigned x) {
return x != 0 && (x & (x - 1)) == 0;
}
inline void queue_init(queue_t &q, unsigned size) {
assert(is_power_of_2(size));
q.rdptr = 0;
q.wrptr = 0;
q.size = size;
q.mask = size - 1; // Assumes power of two.
}
inline int queue_is_empty(const queue_t &q) {
return q.wrptr == q.rdptr;
}
inline int queue_is_full(const queue_t &q) {
return q.wrptr - q.rdptr == q.size;
}
inline void queue_push_word(queue_t &q, unsigned array[], unsigned data)
{
assert(!queue_is_full(q));
array[q.wrptr++ & q.mask] = data;
}
inline unsigned queue_pop_word(queue_t &q, unsigned array[]) {
assert(!queue_is_empty(q));
return array[q.rdptr++ & q.mask];
}
inline void queue_push_byte(queue_t &q, unsigned char array[], unsigned data)
{
assert(!queue_is_full(q));
array[q.wrptr++ & q.mask] = data;
}
inline unsigned queue_pop_byte(queue_t &q, unsigned char array[]) {
assert(!queue_is_empty(q));
return array[q.rdptr++ & q.mask];
}
inline unsigned queue_items(const queue_t &q) {
return q.wrptr - q.rdptr;
}
inline unsigned queue_space(const queue_t &q) {
return q.size - queue_items(q);
}
#endif /* QUEUE_H_ */

13
module_queue/src/queue.xc Normal file
View File

@@ -0,0 +1,13 @@
#include "queue.h"
// Force external definitions of inline functions.
extern inline int is_power_of_2(unsigned x);
extern inline void queue_init(queue_t &q, unsigned size);
extern inline int queue_is_empty(const queue_t &q);
extern inline int queue_is_full(const queue_t &q);
extern inline void queue_push_word(queue_t &q, unsigned array[], unsigned data);
extern inline unsigned queue_pop_word(queue_t &q, unsigned array[]);
extern inline void queue_push_byte(queue_t &q, unsigned char array[], unsigned data);
extern inline unsigned queue_pop_byte(queue_t &q, unsigned char array[]);
extern inline unsigned queue_space(const queue_t &q);
extern inline unsigned queue_items(const queue_t &q);

View File

@@ -0,0 +1,9 @@
<Add title here>
================
:scope: <Put one of Roadmap, Example, Early Development or General Use>
:description: <Add one line here>
:keywords: <Add comma separated list of keywords>
:boards: <Add comma separated list of supported boards>
<Add description of software block>

View File

@@ -142,7 +142,7 @@ static inline void doI2SClocks(unsigned divide)
/* I2S delivery thread */ /* I2S delivery thread */
#pragma unsafe arrays #pragma unsafe arrays
{unsigned, unsigned} deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsigned curSamFreq, chanend ?c_dig_rx, chanend ?c_adc) {unsigned, unsigned} static deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsigned curSamFreq, chanend ?c_dig_rx, chanend ?c_adc)
{ {
unsigned sample; unsigned sample;
unsigned underflow = 0; unsigned underflow = 0;
@@ -209,8 +209,8 @@ static inline void doI2SClocks(unsigned divide)
} }
else else
{ {
#ifndef MIXER // Interfaces straight to decouple()
underflow = inuint(c_out); underflow = inuint(c_out);
#ifndef MIXER // Interfaces straight to decouple()
#if NUM_USB_CHAN_IN > 0 #if NUM_USB_CHAN_IN > 0
#pragma loop unroll #pragma loop unroll
@@ -238,7 +238,18 @@ static inline void doI2SClocks(unsigned divide)
} }
} }
#endif #endif
#else #else /* ifndef MIXER */
if(underflow)
{
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
samplesOut[i] = underflowWord;
}
}
else
{
#pragma loop unroll #pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++) for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{ {
@@ -248,6 +259,7 @@ static inline void doI2SClocks(unsigned divide)
#endif #endif
samplesOut[i] = tmp; samplesOut[i] = tmp;
} }
}
#pragma loop unroll #pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_IN; i++) for(int i = 0; i < NUM_USB_CHAN_IN; i++)
@@ -387,8 +399,8 @@ static inline void doI2SClocks(unsigned divide)
} }
else else
{ {
#ifndef MIXER // Interfaces straight to decouple()
underflow = inuint(c_out); underflow = inuint(c_out);
#ifndef MIXER // Interfaces straight to decouple()
#if NUM_USB_CHAN_IN > 0 #if NUM_USB_CHAN_IN > 0
#pragma loop unroll #pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_IN; i++) for(int i = 0; i < NUM_USB_CHAN_IN; i++)
@@ -416,6 +428,16 @@ static inline void doI2SClocks(unsigned divide)
} }
#endif #endif
#else /* ifndef MIXER */ #else /* ifndef MIXER */
if(underflow)
{
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
samplesOut[i] = underflowWord;
}
}
else
{
#pragma loop unroll #pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++) for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{ {
@@ -425,6 +447,7 @@ static inline void doI2SClocks(unsigned divide)
#endif #endif
samplesOut[i] = tmp; samplesOut[i] = tmp;
} }
}
#pragma loop unroll #pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_IN; i++) for(int i = 0; i < NUM_USB_CHAN_IN; i++)
@@ -711,7 +734,7 @@ static inline void doI2SClocks(unsigned divide)
/* This function is a dummy version of the deliver thread that does not /* This function is a dummy version of the deliver thread that does not
connect to the codec ports. It is used during DFU reset. */ connect to the codec ports. It is used during DFU reset. */
{unsigned,unsigned} dummy_deliver(chanend c_out) {unsigned,unsigned} static dummy_deliver(chanend c_out)
{ {
while (1) while (1)
{ {

View File

@@ -38,13 +38,13 @@ static int clockValid[NUM_CLOCKS]; /* Store current val
static int clockInt[NUM_CLOCKS]; /* Interupt flag for clocks */ static int clockInt[NUM_CLOCKS]; /* Interupt flag for clocks */
static int clockId[NUM_CLOCKS]; static int clockId[NUM_CLOCKS];
int abs(int x) static int abs(int x)
{ {
if (x < 0) return -x; if (x < 0) return -x;
return x; return x;
} }
int channelContainsControlToken(chanend x) static int channelContainsControlToken(chanend x)
{ {
unsigned char tmpc; unsigned char tmpc;
@@ -58,7 +58,7 @@ int channelContainsControlToken(chanend x)
} }
void outInterrupt(chanend c_interruptControl, int value) static void outInterrupt(chanend c_interruptControl, int value)
{ {
/* Non-blocking check for control token */ /* Non-blocking check for control token */
//if (channelContainsControlToken(c_interruptControl)) //if (channelContainsControlToken(c_interruptControl))

View File

@@ -56,6 +56,7 @@
#if ((MCLK_48 % MIN_FREQ) == 0) #if ((MCLK_48 % MIN_FREQ) == 0)
#define MIN_FREQ_48 MIN_FREQ #define MIN_FREQ_48 MIN_FREQ
/* * 2 required since we want the next 44.1 based freq above MIN_FREQ */
#define MIN_FREQ_44 (((44100*512)/((48000 * 512)/MIN_FREQ))*2) #define MIN_FREQ_44 (((44100*512)/((48000 * 512)/MIN_FREQ))*2)
#endif #endif
@@ -246,9 +247,62 @@
#define PID_AUDIO_2 (0x0002) #define PID_AUDIO_2 (0x0002)
#endif #endif
/* Device release number in BCD: 0xJJMNi */ /* Device release number in BCD: 0xJJMN */
#define BCD_DEVICE_J 6
#define BCD_DEVICE_M 3
#define BCD_DEVICE_N 2
#ifndef BCD_DEVICE #ifndef BCD_DEVICE
#define BCD_DEVICE (0x0620) #define BCD_DEVICE ((BCD_DEVICE_J << 8) | ((BCD_DEVICE_M & 0xF) << 4) | (BCD_DEVICE_N & 0xF))
#endif
/* Sample Sub-slot size (bytes) for High Speed. Default is 4 bytes */
#ifndef SAMPLE_SUBSLOT_SIZE_HS
#define SAMPLE_SUBSLOT_SIZE_HS 4
#endif
#if (SAMPLE_SUBSLOT_SIZE_HS != 2) && (SAMPLE_SUBSLOT_SIZE_HS != 3) && (SAMPLE_SUBSLOT_SIZE_HS != 4)
#error Only SAMPLE_SUBSLOT_SIZE_HS 2, 3 or 4 supported #SAMPLE_SUBSLOT_SIZE_HS
#endif
/* Sample Sub-slot size (bytes) for Full Speed. Default is 3 bytes */
#ifndef SAMPLE_SUBSLOT_SIZE_FS
#define SAMPLE_SUBSLOT_SIZE_FS 3
#endif
#if (SAMPLE_SUBSLOT_SIZE_FS != 2) && (SAMPLE_SUBSLOT_SIZE_FS != 3) && (SAMPLE_SUBSLOT_SIZE_FS != 4)
#error Only SAMPLE_SUBSLOT_SIZE_FS 2, 3 or 4 supported
#endif
/* Sample bit resolution for High Speed. Default 24bit*/
#ifndef SAMPLE_BIT_RESOLUTION_HS
#define SAMPLE_BIT_RESOLUTION_HS 24
#endif
#if (SAMPLE_BIT_RESOLUTION_HS/8) > SAMPLE_SUBSLOT_SIZE_HS
#error SAMPLE_BIT_RESOLUTION_HS is too big for SAMPLE_SUBSLOT_SIZE_HS
#endif
/* Sample bit resolution for Full Speed. Default 24bit*/
#ifndef SAMPLE_BIT_RESOLUTION_FS
#define SAMPLE_BIT_RESOLUTION_FS 24
#endif
#if (SAMPLE_BIT_RESOLUTION_FS/8) > SAMPLE_SUBSLOT_SIZE_FS
#error SAMPLE_BIT_RESOLUTION_FS is too big for SAMPLE_SUBSLOT_SIZE_FS
#endif
/* By default base the iAP version number on USB BCD_DEVICE */
#if defined(IAP)
#ifndef ACCESSORY_FIRMWARE_MAJOR
#define ACCESSORY_FIRMWARE_MAJOR BCD_DEVICE_J
#endif
#ifndef ACCESSORY_FIRMWARE_MINOR
#define ACCESSORY_FIRMWARE_MINOR BCD_DEVICE_M
#endif
#ifndef ACCESSORY_FIRMWARE_POINT
#define ACCESSORY_FIRMWARE_POINT BCD_DEVICE_N
#endif
#endif #endif
/* Addition interfaces based on defines */ /* Addition interfaces based on defines */

View File

@@ -51,10 +51,10 @@ extern unsigned char mixSel[MIX_INPUTS];
/* Global var for current frequency, set to default freq */ /* Global var for current frequency, set to default freq */
unsigned int g_curSamFreq = DEFAULT_FREQ; unsigned int g_curSamFreq = DEFAULT_FREQ;
unsigned int g_curSamFreq48000Family = DEFAULT_FREQ % 48000 == 0; unsigned int g_curSamFreq48000Family = DEFAULT_FREQ % 48000 == 0;
unsigned int g_curSamFreqMultiplier = DEFAULT_FREQ / 48000; unsigned int g_curSamFreqMultiplier = DEFAULT_FREQ / (DEFAULT_MCLK_FREQ / 512);
/* Store an int into a char array: Note this allows non-word aligned access unlike reinerpret cast */ /* Store an int into a char array: Note this allows non-word aligned access unlike reinerpret cast */
void storeInt(unsigned char buffer[], int index, int val) static void storeInt(unsigned char buffer[], int index, int val)
{ {
buffer[index+3] = val>>24; buffer[index+3] = val>>24;
buffer[index+2] = val>>16; buffer[index+2] = val>>16;
@@ -63,13 +63,13 @@ void storeInt(unsigned char buffer[], int index, int val)
} }
/* Store an short into a char array: Note this allows non-word aligned access unlike reinerpret cast */ /* Store an short into a char array: Note this allows non-word aligned access unlike reinerpret cast */
void storeShort(unsigned char buffer[], int index, short val) static void storeShort(unsigned char buffer[], int index, short val)
{ {
buffer[index+1] = val>>8; buffer[index+1] = val>>8;
buffer[index] = val; buffer[index] = val;
} }
void storeFreq(unsigned char buffer[], int &i, int freq) static void storeFreq(unsigned char buffer[], int &i, int freq)
{ {
storeInt(buffer, i, freq); storeInt(buffer, i, freq);
i+=4; i+=4;
@@ -81,7 +81,7 @@ void storeFreq(unsigned char buffer[], int &i, int freq)
} }
unsigned longMul(unsigned a, unsigned b, int prec) static unsigned longMul(unsigned a, unsigned b, int prec)
{ {
unsigned x,y; unsigned x,y;
unsigned ret; unsigned ret;
@@ -94,12 +94,12 @@ unsigned longMul(unsigned a, unsigned b, int prec)
return ret; return ret;
} }
void setG_curSamFreqMultiplier(int x) { static void setG_curSamFreqMultiplier(int x) {
asm(" stw %0, dp[g_curSamFreqMultiplier]" :: "r"(x)); asm(" stw %0, dp[g_curSamFreqMultiplier]" :: "r"(x));
} }
/* Update master volume i.e. i.e update weights for all channels */ /* Update master volume i.e. i.e update weights for all channels */
void updateMasterVol( int unitID, chanend ?c_mix_ctl) static void updateMasterVol( int unitID, chanend ?c_mix_ctl)
{ {
int x; int x;
#ifndef OUT_VOLUME_IN_MIXER #ifndef OUT_VOLUME_IN_MIXER
@@ -168,7 +168,7 @@ void updateMasterVol( int unitID, chanend ?c_mix_ctl)
} }
} }
void updateVol(int unitID, int channel, chanend ?c_mix_ctl) static void updateVol(int unitID, int channel, chanend ?c_mix_ctl)
{ {
int x; int x;
#ifndef OUT_VOLUME_IN_MIXER #ifndef OUT_VOLUME_IN_MIXER
@@ -583,10 +583,10 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
break; /* FU_USBIN */ break; /* FU_USBIN */
#ifdef MIXER #if defined(MIXER) && (MAX_MIX_COUNT > 0)
case ID_XU_OUT: case ID_XU_OUT:
{ {
if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_H2D) /* Direction: Host-to-device */ if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D) /* Direction: Host-to-device */
{ {
unsigned volume = 0; unsigned volume = 0;
int c = sp.wValue & 0xff; int c = sp.wValue & 0xff;
@@ -624,7 +624,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
break; break;
case ID_XU_IN: case ID_XU_IN:
if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_H2D) /* Direction: Host-to-device */ if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D) /* Direction: Host-to-device */
{ {
unsigned volume = 0; unsigned volume = 0;
int c = sp.wValue & 0xff; int c = sp.wValue & 0xff;
@@ -663,7 +663,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
int cn = sp.wValue & 0xff; /* Channel number */ int cn = sp.wValue & 0xff; /* Channel number */
/* Check for Get or Set */ /* Check for Get or Set */
if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT) if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_OUT)
{ {
/* Direction: Host-to-device */ /* Host-to-device */ /* Direction: Host-to-device */ /* Host-to-device */
datalength = XUD_GetBuffer(ep0_out, buffer); datalength = XUD_GetBuffer(ep0_out, buffer);
@@ -720,7 +720,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
case ID_MIXER_1: case ID_MIXER_1:
if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT) /* Direction: Host-to-device */ if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_OUT) /* Direction: Host-to-device */
{ {
unsigned volume = 0; unsigned volume = 0;
@@ -807,26 +807,25 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
while(1) while(1)
{ {
if((currentFreq48 <= maxFreq)) if((currentFreq44 <= maxFreq) && (currentFreq44 >= MIN_FREQ))
{ {
/* Note i passed byref here */
storeFreq(buffer, i, currentFreq44); storeFreq(buffer, i, currentFreq44);
num_freqs++; num_freqs++;
currentFreq44*=2; currentFreq44*=2;
}
if((currentFreq48 <= maxFreq))
{
/* Note i passed byref here */
storeFreq(buffer, i, currentFreq48); storeFreq(buffer, i, currentFreq48);
num_freqs++; num_freqs++;
currentFreq48*=2; currentFreq48*=2;
} }
else if((currentFreq44 <= maxFreq))
{
storeFreq(buffer, i, currentFreq44);
num_freqs++;
currentFreq44*=2;
}
else else
{
break; break;
} }
}
storeShort(buffer, 0, num_freqs); storeShort(buffer, 0, num_freqs);
return XUD_DoGetRequest(ep0_out, ep0_in, buffer, i, sp.wLength); return XUD_DoGetRequest(ep0_out, ep0_in, buffer, i, sp.wLength);
@@ -884,7 +883,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
break; /* case: RANGE */ break; /* case: RANGE */
} }
#ifdef MIXER #if defined (MIXER) && (MAX_MIX_COUNT > 0)
case MEM: /* Memory Requests (5.2.7.1) */ case MEM: /* Memory Requests (5.2.7.1) */
unitID = sp.wIndex >> 8; unitID = sp.wIndex >> 8;
@@ -893,7 +892,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
{ {
case ID_MIXER_1: case ID_MIXER_1:
if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_IN) if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_IN)
{ {
int length = 0; int length = 0;

View File

@@ -191,7 +191,7 @@ unsigned char devQualDesc_Null[] =
#define LEN_XU_IN (0) #define LEN_XU_IN (0)
#endif #endif
#ifdef MIXER #if defined (MIXER) && (MAX_MIX_COUNT > 0)
#define LEN_XU_MIX (17) #define LEN_XU_MIX (17)
#define MIX_BMCONTROLS_LEN_TMP ((MAX_MIX_COUNT * MIX_INPUTS) / 8) #define MIX_BMCONTROLS_LEN_TMP ((MAX_MIX_COUNT * MIX_INPUTS) / 8)
@@ -242,45 +242,33 @@ unsigned char devQualDesc_Null[] =
#define OUTPUT_ALT_LENGTH (OUTPUT_ALT_LENGTH_ADAT + OUTPUT_ALT_LENGTH_DSD) #define OUTPUT_ALT_LENGTH (OUTPUT_ALT_LENGTH_ADAT + OUTPUT_ALT_LENGTH_DSD)
// Positions in strDescs_Audio2 // Positions in strDescs
#define INTERNAL_CLOCK_STRING_INDEX (14) enum {
#define SPDIF_CLOCK_STRING_INDEX (15) INTERNAL_CLOCK_STRING_INDEX = 14,
#ifdef SPDIF_RX #ifdef SPDIF_RX
#define ADAT_CLOCK_STRING_INDEX (SPDIF_CLOCK_STRING_INDEX + 1) SPDIF_CLOCK_STRING_INDEX,
#else
#define ADAT_CLOCK_STRING_INDEX (SPDIF_CLOCK_STRING_INDEX)
#endif #endif
#ifdef ADAT_RX #ifdef ADAT_RX
#define DFU_STRING_INDEX (ADAT_CLOCK_STRING_INDEX + 1) ADAT_CLOCK_STRING_INDEX,
#else
#define DFU_STRING_INDEX (ADAT_CLOCK_STRING_INDEX)
#endif #endif
#ifdef DFU #ifdef DFU
#define MIDI_OUT_STRING_INDEX (DFU_STRING_INDEX + 1) DFU_STRING_INDEX,
#else
#define MIDI_OUT_STRING_INDEX (DFU_STRING_INDEX)
#endif #endif
#define MIDI_IN_STRING_INDEX (MIDI_OUT_STRING_INDEX + 1)
#ifdef MIDI #ifdef MIDI
#define OUTPUT_INTERFACE_STRING_INDEX (MIDI_OUT_STRING_INDEX + 2) MIDI_OUT_STRING_INDEX,
#else MIDI_IN_STRING_INDEX,
#define OUTPUT_INTERFACE_STRING_INDEX (MIDI_OUT_STRING_INDEX)
#endif #endif
OUTPUT_INTERFACE_STRING_INDEX,
#define INPUT_INTERFACE_STRING_INDEX (OUTPUT_INTERFACE_STRING_INDEX + NUM_USB_CHAN_OUT) OUTPUT_INTERFACE_LAST_STRING_INDEX = OUTPUT_INTERFACE_STRING_INDEX + NUM_USB_CHAN_OUT - 1,
INPUT_INTERFACE_STRING_INDEX,
#define MIXER_STRING_INDEX (INPUT_INTERFACE_STRING_INDEX + NUM_USB_CHAN_IN) INPUT_INTERFACE_LAST_STRING_INDEX = INPUT_INTERFACE_STRING_INDEX + NUM_USB_CHAN_IN - 1,
#ifdef MIXER #ifdef MIXER
#define IAP_INTERFACE_STRING_INDEX (MIXER_STRING_INDEX + MAX_MIX_COUNT) MIXER_STRING_INDEX,
#else
#define IAP_INTERFACE_STRING_INDEX (MIXER_STRING_INDEX)
#endif #endif
#ifdef IAP
IAP_INTERFACE_STRING_INDEX,
#endif
};
#ifdef HID_CONTROLS #ifdef HID_CONTROLS
unsigned char hidReportDescriptor[] = { unsigned char hidReportDescriptor[] = {
@@ -325,6 +313,8 @@ unsigned char hidReportDescriptor[] = {
*/ */
#define MAX_PACKET_SIZE_OUT_HS ((((MAX_FREQ+7999)/8000)+1) * NUM_USB_CHAN_OUT * 4) #define MAX_PACKET_SIZE_OUT_HS ((((MAX_FREQ+7999)/8000)+1) * NUM_USB_CHAN_OUT * 4)
#define MAX_PACKET_SIZE_OUT_FS ((((MAX_FREQ_A1+999)/1000)+1) * NUM_USB_CHAN_OUT_FS * 3) // Samples per channel #define MAX_PACKET_SIZE_OUT_FS ((((MAX_FREQ_A1+999)/1000)+1) * NUM_USB_CHAN_OUT_FS * 3) // Samples per channel
#define MAX_PACKET_SIZE_IN_HS ((((MAX_FREQ+7999)/8000)+1) * NUM_USB_CHAN_IN * 4)
#define MAX_PACKET_SIZE_IN_FS ((((MAX_FREQ_A1+999)/1000)+1) * NUM_USB_CHAN_IN_FS * 3) // Samples per channel
/* Configuration Descriptor for Audio 2.0 (HS) operation */ /* Configuration Descriptor for Audio 2.0 (HS) operation */
unsigned char cfgDesc_Audio2[] = unsigned char cfgDesc_Audio2[] =
@@ -698,7 +688,7 @@ unsigned char cfgDesc_Audio2[] =
#ifdef MIXER #if defined (MIXER) && (MAX_MIX_COUNT > 0)
/* Extension Unit Descriptor (4.7.2.12) */ /* Extension Unit Descriptor (4.7.2.12) */
LEN_XU_MIX, /* 0 bLength (15 + p, when p is number of sources) */ LEN_XU_MIX, /* 0 bLength (15 + p, when p is number of sources) */
CS_INTERFACE, /* 1 bDescriptorType */ CS_INTERFACE, /* 1 bDescriptorType */
@@ -849,8 +839,8 @@ unsigned char cfgDesc_Audio2[] =
CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ CS_INTERFACE, /* 1 bDescriptorType: 0x24 */
FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */
FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */
0x04, /* 4 bSubslotSize (Number of bytes per subslot) */ SAMPLE_SUBSLOT_SIZE_HS, /* 4 bSubslotSize (Number of bytes per subslot) */
24, /* 5 bBitResolution (Number of bits used per subslot) */ SAMPLE_BIT_RESOLUTION_HS, /* 5 bBitResolution (Number of bits used per subslot) */
/* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */
0x07, /* 0 bLength: 7 */ 0x07, /* 0 bLength: 7 */
@@ -859,7 +849,6 @@ unsigned char cfgDesc_Audio2[] =
0x05, /* 3 bmAttributes (bitmap) */ 0x05, /* 3 bmAttributes (bitmap) */
MAX_PACKET_SIZE_OUT_HS&0xff, /* 4 wMaxPacketSize */ MAX_PACKET_SIZE_OUT_HS&0xff, /* 4 wMaxPacketSize */
(MAX_PACKET_SIZE_OUT_HS&0xff00)>>8, /* 5 wMaxPacketSize */ (MAX_PACKET_SIZE_OUT_HS&0xff00)>>8, /* 5 wMaxPacketSize */
//0, 4, // 1024
1, /* 6 bInterval */ 1, /* 6 bInterval */
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */
@@ -908,7 +897,7 @@ unsigned char cfgDesc_Audio2[] =
CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ CS_INTERFACE, /* 1 bDescriptorType: 0x24 */
FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */
FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */
0x04, /* 4 bSubslotSize (Number of bytes per subslot) */ SAMPLE_SUBSLOT_SIZE_HS, /* 4 bSubslotSize (Number of bytes per subslot) */
32, /* 5 bBitResolution (Number of bits used per subslot) */ 32, /* 5 bBitResolution (Number of bits used per subslot) */
/* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */
@@ -916,7 +905,8 @@ unsigned char cfgDesc_Audio2[] =
USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */
0x01, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 0x01, /* 2 bEndpointAddress (D7: 0:out, 1:in) */
0x05, /* 3 bmAttributes (bitmap) */ 0x05, /* 3 bmAttributes (bitmap) */
0,4, /* 4 wMaxPacketSize */ MAX_PACKET_SIZE_OUT_HS&0xff, /* 4 wMaxPacketSize */
(MAX_PACKET_SIZE_OUT_HS&0xff00)>>8, /* 5 wMaxPacketSize */
1, /* 6 bInterval */ 1, /* 6 bInterval */
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */
@@ -967,15 +957,16 @@ unsigned char cfgDesc_Audio2[] =
CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ CS_INTERFACE, /* 1 bDescriptorType: 0x24 */
FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */
FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */
0x04, /* 4 bSubslotSize (Number of bytes per subslot) */ SAMPLE_SUBSLOT_SIZE_HS, /* 4 bSubslotSize (Number of bytes per subslot) */
24, /* 5 bBitResolution (Number of bits used per subslot) */ SAMPLE_BIT_RESOLUTION_HS, /* 5 bBitResolution (Number of bits used per subslot) */
/* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */
0x07, /* 0 bLength: 7 */ 0x07, /* 0 bLength: 7 */
USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */
0x01, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 0x01, /* 2 bEndpointAddress (D7: 0:out, 1:in) */
0x05, /* 3 bmAttributes (bitmap) */ 0x05, /* 3 bmAttributes (bitmap) */
0,4, /* 4 wMaxPacketSize */ MAX_PACKET_SIZE_OUT_HS&0xff, /* 4 wMaxPacketSize */
(MAX_PACKET_SIZE_OUT_HS&0xff00)>>8, /* 5 wMaxPacketSize */
1, /* 6 bInterval */ 1, /* 6 bInterval */
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */
@@ -1038,15 +1029,16 @@ unsigned char cfgDesc_Audio2[] =
CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ CS_INTERFACE, /* 1 bDescriptorType: 0x24 */
FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */
FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */
0x04, /* 4 bSubslotSize (Number of bytes per subslot) */ SAMPLE_SUBSLOT_SIZE_HS, /* 4 bSubslotSize (Number of bytes per subslot) */
24, /* 5 bBitResolution (Number of bits used per subslot) */ SAMPLE_BIT_RESOLUTION_HS, /* 5 bBitResolution (Number of bits used per subslot) */
/* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */
0x07, /* 0 bLength: 7 */ 0x07, /* 0 bLength: 7 */
USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */
0x82, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 0x82, /* 2 bEndpointAddress (D7: 0:out, 1:in) */
5, /* 3 bmAttributes (bitmap) */ 5, /* 3 bmAttributes (bitmap) */
0,4, /* 4 wMaxPacketSize */ MAX_PACKET_SIZE_IN_HS&0xff, /* 4 wMaxPacketSize */
(MAX_PACKET_SIZE_IN_HS&0xff00)>>8, /* 5 wMaxPacketSize */
1, /* 6 bInterval */ 1, /* 6 bInterval */
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */
@@ -1087,15 +1079,16 @@ unsigned char cfgDesc_Audio2[] =
CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ CS_INTERFACE, /* 1 bDescriptorType: 0x24 */
FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */
FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */
0x04, /* 4 bSubslotSize (Number of bytes per subslot) */ SAMPLE_SUBSLOT_SIZE_HS, /* 4 bSubslotSize (Number of bytes per subslot) */
24, /* 5 bBitResolution (Number of bits used per subslot) */ SAMPLE_BIT_RESOLUTION_HS, /* 5 bBitResolution (Number of bits used per subslot) */
/* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */
0x07, /* 0 bLength: 7 */ 0x07, /* 0 bLength: 7 */
USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */
0x82, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 0x82, /* 2 bEndpointAddress (D7: 0:out, 1:in) */
5, /* 3 bmAttributes (bitmap) */ 5, /* 3 bmAttributes (bitmap) */
0,4, /* 4 wMaxPacketSize */ MAX_PACKET_SIZE_IN_HS&0xff, /* 4 wMaxPacketSize */
(MAX_PACKET_SIZE_IN_HS&0xff00)>>8, /* 5 wMaxPacketSize */
1, /* 6 bInterval */ 1, /* 6 bInterval */
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */
@@ -1248,7 +1241,7 @@ unsigned char cfgDesc_Audio2[] =
0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */ 0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */
EP_ADR_OUT_MIDI, /* 2 bEndpointAddress : OUT Endpoint 3. (field size 1 bytes) */ EP_ADR_OUT_MIDI, /* 2 bEndpointAddress : OUT Endpoint 3. (field size 1 bytes) */
0x02, /* 3 bmAttributes : Bulk, not shared. (field size 1 bytes) */ 0x02, /* 3 bmAttributes : Bulk, not shared. (field size 1 bytes) */
0x00, /* 4 wMaxPacketSize : 64 bytes per packet. (field size 2 bytes) - has to be 0x200 for compliance*/ 0x00, /* 4 wMaxPacketSize : 512 bytes per packet. (field size 2 bytes) - has to be 0x200 for compliance*/
0x02, /* 5 wMaxPacketSize */ 0x02, /* 5 wMaxPacketSize */
0x00, /* 6 bInterval : Ignored for Bulk. Set to zero. (field size 1 bytes) */ 0x00, /* 6 bInterval : Ignored for Bulk. Set to zero. (field size 1 bytes) */
0x00, /* 7 bRefresh : Unused. (field size 1 bytes) */ 0x00, /* 7 bRefresh : Unused. (field size 1 bytes) */
@@ -1266,7 +1259,7 @@ unsigned char cfgDesc_Audio2[] =
0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */ 0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */
EP_ADR_IN_MIDI, /* 2 bEndpointAddress : IN Endpoint 3. (field size 1 bytes) */ EP_ADR_IN_MIDI, /* 2 bEndpointAddress : IN Endpoint 3. (field size 1 bytes) */
0x02, /* 3 bmAttributes : Bulk, not shared. (field size 1 bytes) */ 0x02, /* 3 bmAttributes : Bulk, not shared. (field size 1 bytes) */
0x00, /* 4 wMaxPacketSize : 64 bytes per packet. (field size 2 bytes) - has to be 0x200 for compliance*/ 0x00, /* 4 wMaxPacketSize : 512 bytes per packet. (field size 2 bytes) - has to be 0x200 for compliance*/
0x02, /* 5 wMaxPacketSize */ 0x02, /* 5 wMaxPacketSize */
0x00, /* 6 bInterval : Ignored for Bulk. Set to zero. (field size 1 bytes) */ 0x00, /* 6 bInterval : Ignored for Bulk. Set to zero. (field size 1 bytes) */
0x00, /* 7 bRefresh : Unused. (field size 1 bytes) */ 0x00, /* 7 bRefresh : Unused. (field size 1 bytes) */
@@ -1394,44 +1387,8 @@ unsigned char cfgDesc_Audio2[] =
#endif #endif
}; };
/* String table */
#ifdef SPDIF_RX
#define SPDIF_RX_NUM_STRS 1
#else
#define SPDIF_RX_NUM_STRS 0
#endif
#ifdef ADAT_RX
#define ADAT_RX_NUM_STRS 1
#else
#define ADAT_RX_NUM_STRS 0
#endif
#ifdef MIDI
#define MIDI_NUM_STRS 2
#else
#define MIDI_NUM_STRS 0
#endif
#ifdef DFU
#define DFU_NUM_STRS 1
#else
#define DFU_NUM_STRS 0
#endif
#define STR_INDEX_OUT_CHAN (10 + SPDIF_RX_NUM_STRS + ADAT_RX_NUM_STRS + MIDI_NUM_STRS + DFU_NUM_STRS)
#define STR_INDEX_IN_CHAN (STR_INDEX_OUT_CHAN + NUM_USB_CHAN_OUT)
#define APPEND_VENDOR_STR(x) VENDOR_STR" "#x #define APPEND_VENDOR_STR(x) VENDOR_STR" "#x
#define APPEND_PRODUCT_STR_A2(x) PRODUCT_STR_A2 " "#x #define APPEND_PRODUCT_STR_A2(x) PRODUCT_STR_A2 " "#x
@@ -1446,9 +1403,12 @@ unsigned char cfgDesc_Audio2[] =
#endif #endif
#endif #endif
#define STR_USENG 0x0409
static unsigned char strDescs[][40] = static unsigned char strDescs[][40] =
{ {
"Langids", // 0 LangIDs place holder { STR_USENG & 0xff, STR_USENG >> 8, '\0'}, // 0 LangID
APPEND_VENDOR_STR(), // 1 iManufacturer (at MANUFACTURER_STRING_INDEX) APPEND_VENDOR_STR(), // 1 iManufacturer (at MANUFACTURER_STRING_INDEX)
"",//SERIAL_STR, // 2 iSerialNumber (at SERIAL_STR_INDEX) "",//SERIAL_STR, // 2 iSerialNumber (at SERIAL_STR_INDEX)
@@ -1853,8 +1813,8 @@ unsigned char cfgDesc_Audio1[] =
0x02, /* Subtype - FORMAT_TYPE */ 0x02, /* Subtype - FORMAT_TYPE */
0x01, /* Format type - FORMAT_TYPE_1 */ 0x01, /* Format type - FORMAT_TYPE_1 */
NUM_USB_CHAN_OUT_FS, /* nrChannels */ NUM_USB_CHAN_OUT_FS, /* nrChannels */
0x03, /* subFrameSize - 4 bytes per slot */ SAMPLE_SUBSLOT_SIZE_FS, /* subFrameSize */
24, /* bitResolution - 24bit */ SAMPLE_BIT_RESOLUTION_FS, /* bitResolution */
0x04, /* SamFreqType - 4 sample freq */ 0x04, /* SamFreqType - 4 sample freq */
0x44, 0xAC, 0x00, /* sampleFreq - 44.1Khz */ 0x44, 0xAC, 0x00, /* sampleFreq - 44.1Khz */
0x80, 0xBB, 0x00, /* sampleFreq - 48KHz */ 0x80, 0xBB, 0x00, /* sampleFreq - 48KHz */
@@ -1935,9 +1895,9 @@ unsigned char cfgDesc_Audio1[] =
CS_INTERFACE, CS_INTERFACE,
0x02, /* Subtype - FORMAT_TYPE */ 0x02, /* Subtype - FORMAT_TYPE */
0x01, /* Format type - FORMAT_TYPE_1 */ 0x01, /* Format type - FORMAT_TYPE_1 */
NUM_USB_CHAN_IN_FS, /* bNrChannels - 2 */ NUM_USB_CHAN_IN_FS, /* bNrChannels - Typically 2 */
0x03, /* subFrameSize - 4 bytes per slot */ SAMPLE_SUBSLOT_SIZE_FS, /* subFrameSize - Typically 4 bytes per slot */
24, /* bitResolution - 24bit */ SAMPLE_BIT_RESOLUTION_FS, /* bitResolution - Typically 24bit */
0x04, /* SamFreqType - 4 sample freq */ 0x04, /* SamFreqType - 4 sample freq */
0x44, 0xAC, 0x00, /* sampleFreq - 44.1Khz */ 0x44, 0xAC, 0x00, /* sampleFreq - 44.1Khz */
0x80, 0xBB, 0x00, /* sampleFreq - 48KHz */ 0x80, 0xBB, 0x00, /* sampleFreq - 48KHz */
@@ -2010,24 +1970,5 @@ unsigned char cfgDesc_Audio1[] =
#endif #endif
}; };
#endif
#define APPEND_VENDOR_STR(x) VENDOR_STR#x
#if 0
static unsigned char strDescs_Audio1[][40] =
{
"Langids", /* String 0 (LangIDs) place holder */
APPEND_VENDOR_STR(), // 1 iManufacturer
APPEND_VENDOR_STR(USB Audio 1.0), // 2 iProduct and iInterface for control interface
"",//SERIAL_STR, // 3 iSerialNumber
APPEND_VENDOR_STR(USB 1.0 Audio Out), // 4 iInterface for Streaming interaces
APPEND_VENDOR_STR(USB 1.0 Audio In), // 5
APPEND_VENDOR_STR(Audio 1.0 Output), // 6 "USB Input Terminal" (User sees as output from host)
APPEND_VENDOR_STR(Audio 1.0 Input), // 7 "USB Output Terminal" (User sees as input to host)
APPEND_VENDOR_STR(DFU) // 8 iInterface for DFU interface
};
#endif #endif
#endif #endif

View File

@@ -16,10 +16,6 @@
* \param c_usb_test Optional chanend to be connected to XUD if test modes required. * \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, 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 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
);
#endif #endif

View File

@@ -100,24 +100,11 @@ unsigned g_curUsbSpeed = 0;
extern unsigned g_iap_reset; extern unsigned g_iap_reset;
#endif #endif
#define STR_USENG 0x0409
#define DESC_STR_LANGIDS \
{ \
STR_USENG & 0xff, /* 2 wLangID[0] */ \
STR_USENG>>8, /* 3 wLangID[0] */ \
'\0' \
}
#ifdef NATIVE_DSD #ifdef NATIVE_DSD
/* We remember if we are in DSD mode to avoid Configuring the DAC too often - thus avoiding pops and clicks */ /* We remember if we are in DSD mode to avoid Configuring the DAC too often - thus avoiding pops and clicks */
unsigned g_dsdMode = 0; unsigned g_dsdMode = 0;
#endif #endif
/* String descriptors */
static unsigned char strDesc_langIDs[] = DESC_STR_LANGIDS;
void VendorAudioRequestsInit(chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl); void VendorAudioRequestsInit(chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl);
/* Endpoint 0 function. Handles all requests to the device */ /* Endpoint 0 function. Handles all requests to the device */
@@ -193,43 +180,36 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
} }
#endif #endif
/* Copy langIDs string desc into string[0] */
/* TODO: Macro? */
#if defined(AUDIO_CLASS_FALLBACK) || (AUDIO_CLASS == 1)
//safememcpy(strDescs_Audio1[0], strDesc_langIDs, sizeof(strDesc_langIDs));
#endif
safememcpy(strDescs[0], strDesc_langIDs, sizeof(strDesc_langIDs));
/* Build up channel string table - By default all channels are marked as analogue /* Build up channel string table - By default all channels are marked as analogue
* TODO We really want to do this an build time... */ * TODO We really want to do this an build time... */
#if defined(SPDIF_RX) && (SPDIF_RX_INDEX != 0) #if defined(SPDIF_RX) && (SPDIF_RX_INDEX != 0)
safestrcpy(strDescs[SPDIF_RX_INDEX + STR_INDEX_IN_CHAN], "S/PDIF 1"); safestrcpy(strDescs[SPDIF_RX_INDEX + INPUT_INTERFACE_STRING_INDEX], "S/PDIF 1");
safestrcpy(strDescs[SPDIF_RX_INDEX + STR_INDEX_IN_CHAN + 1], "S/PDIF 2"); safestrcpy(strDescs[SPDIF_RX_INDEX + INPUT_INTERFACE_STRING_INDEX + 1], "S/PDIF 2");
#endif #endif
#if defined(ADAT_RX) && (ADAT_RX_INDEX != 0) #if defined(ADAT_RX) && (ADAT_RX_INDEX != 0)
safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN], "ADAT 1"); safestrcpy(strDescs[ADAT_RX_INDEX + INPUT_INTERFACE_STRING_INDEX], "ADAT 1");
safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 1], "ADAT 2"); safestrcpy(strDescs[ADAT_RX_INDEX + INPUT_INTERFACE_STRING_INDEX + 1], "ADAT 2");
safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 2], "ADAT 3"); safestrcpy(strDescs[ADAT_RX_INDEX + INPUT_INTERFACE_STRING_INDEX + 2], "ADAT 3");
safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 3], "ADAT 4"); safestrcpy(strDescs[ADAT_RX_INDEX + INPUT_INTERFACE_STRING_INDEX + 3], "ADAT 4");
safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 4], "ADAT 5"); safestrcpy(strDescs[ADAT_RX_INDEX + INPUT_INTERFACE_STRING_INDEX + 4], "ADAT 5");
safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 5], "ADAT 6"); safestrcpy(strDescs[ADAT_RX_INDEX + INPUT_INTERFACE_STRING_INDEX + 5], "ADAT 6");
safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 6], "ADAT 7"); safestrcpy(strDescs[ADAT_RX_INDEX + INPUT_INTERFACE_STRING_INDEX + 6], "ADAT 7");
safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 7], "ADAT 8"); safestrcpy(strDescs[ADAT_RX_INDEX + INPUT_INTERFACE_STRING_INDEX + 7], "ADAT 8");
#endif #endif
#if defined(SPDIF) && (SPDIF_TX_INDEX != 0) /* "Analogue naming gets priority */ #if defined(SPDIF) && (SPDIF_TX_INDEX != 0) /* "Analogue naming gets priority */
safestrcpy(strDescs[SPDIF_TX_INDEX + STR_INDEX_OUT_CHAN], "S/PDIF 1"); safestrcpy(strDescs[SPDIF_TX_INDEX + OUTPUT_INTERFACE_STRING_INDEX], "S/PDIF 1");
safestrcpy(strDescs[SPDIF_TX_INDEX + STR_INDEX_OUT_CHAN + 1], "S/PDIF 2"); safestrcpy(strDescs[SPDIF_TX_INDEX + OUTPUT_INTERFACE_STRING_INDEX + 1], "S/PDIF 2");
#endif #endif
#if defined(ADAT_TX) && (ADAT_TX_INDEX != 0) #if defined(ADAT_TX) && (ADAT_TX_INDEX != 0)
safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN], "ADAT 1"); safestrcpy(strDescs[ADAT_TX_INDEX + OUTPUT_INTERFACE_STRING_INDEX], "ADAT 1");
safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 1], "ADAT 2"); safestrcpy(strDescs[ADAT_TX_INDEX + OUTPUT_INTERFACE_STRING_INDEX + 1], "ADAT 2");
safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 2], "ADAT 3"); safestrcpy(strDescs[ADAT_TX_INDEX + OUTPUT_INTERFACE_STRING_INDEX + 2], "ADAT 3");
safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 3], "ADAT 4"); safestrcpy(strDescs[ADAT_TX_INDEX + OUTPUT_INTERFACE_STRING_INDEX + 3], "ADAT 4");
safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 4], "ADAT 5"); safestrcpy(strDescs[ADAT_TX_INDEX + OUTPUT_INTERFACE_STRING_INDEX + 4], "ADAT 5");
safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 5], "ADAT 6"); safestrcpy(strDescs[ADAT_TX_INDEX + OUTPUT_INTERFACE_STRING_INDEX + 5], "ADAT 6");
safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 6], "ADAT 7"); safestrcpy(strDescs[ADAT_TX_INDEX + OUTPUT_INTERFACE_STRING_INDEX + 6], "ADAT 7");
safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 7], "ADAT 8"); safestrcpy(strDescs[ADAT_TX_INDEX + OUTPUT_INTERFACE_STRING_INDEX + 7], "ADAT 8");
#endif #endif
#ifdef VENDOR_AUDIO_REQS #ifdef VENDOR_AUDIO_REQS
@@ -598,7 +578,10 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
if(g_curUsbSpeed == XUD_SPEED_HS) if(g_curUsbSpeed == XUD_SPEED_HS)
{ {
/* Mod bSlotSize */ /* Mod bSlotSize */
cfgDesc_Audio2[STREAMING_ALT1_OFFSET+4] = 4; cfgDesc_Audio2[STREAMING_ALT1_OFFSET+4] = SAMPLE_SUBSLOT_SIZE_HS;
/* Mod bBitResolution */
cfgDesc_Audio2[STREAMING_ALT1_OFFSET+5] = SAMPLE_BIT_RESOLUTION_HS;
/* wMaxPacketSize */ /* wMaxPacketSize */
cfgDesc_Audio2[STREAMING_ALT1_OFFSET+10] = MAX_PACKET_SIZE_OUT_HS&0xff; cfgDesc_Audio2[STREAMING_ALT1_OFFSET+10] = MAX_PACKET_SIZE_OUT_HS&0xff;
@@ -607,7 +590,10 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
else else
{ {
/* Mod bSlotSize */ /* Mod bSlotSize */
cfgDesc_Audio2[STREAMING_ALT1_OFFSET+4] = 3; cfgDesc_Audio2[STREAMING_ALT1_OFFSET+4] = SAMPLE_SUBSLOT_SIZE_FS;
/* Mod bBitResolution */
cfgDesc_Audio2[STREAMING_ALT1_OFFSET+5] = SAMPLE_BIT_RESOLUTION_FS;
/* wMaxPacketSize */ /* wMaxPacketSize */
cfgDesc_Audio2[STREAMING_ALT1_OFFSET+10] = MAX_PACKET_SIZE_OUT_FS&0xff; cfgDesc_Audio2[STREAMING_ALT1_OFFSET+10] = MAX_PACKET_SIZE_OUT_FS&0xff;

View File

@@ -5,51 +5,81 @@
#include <xs1_user.h> #include <xs1_user.h>
.text
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// void GetLockResource() // void GetLockResource()
.extern GetLockResource
.globl GetLockResource.nstackwords
.linkset GetLockResource.nstackwords, 0
.globl GetLockResource .globl GetLockResource
.text .type GetLockResource, @function
.cc_top GetLockResource.function
.align 2
GetLockResource: GetLockResource:
getr r0, XS1_RES_TYPE_LOCK getr r0, XS1_RES_TYPE_LOCK
retsp 0 retsp 0
.size GetLockResource, .-GetLockResource
.cc_bottom GetLockResource.function
.globl GetLockResource.nstackwords
.globl GetLockResource.maxcores
.globl GetLockResource.maxchanends
.globl GetLockResource.maxtimers
.set GetLockResource.nstackwords, 0
.set GetLockResource.maxcores, 1
.set GetLockResource.maxchanends, 0
.set GetLockResource.maxtimers, 0
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// void ClaimLock(lock l) // void ClaimLock(lock l)
.extern ClaimLock
.globl ClaimLock.nstackwords
.linkset ClaimLock.nstackwords, 0
.globl ClaimLock .globl ClaimLock
.text .type ClaimLock, @function
.cc_top ClaimLock.function
.align 2
ClaimLock: ClaimLock:
in r0, res[r0] in r0, res[r0]
retsp 0 retsp 0
.size ClaimLock, .-ClaimLock
.cc_bottom ClaimLock.function
.globl ClaimLock.nstackwords
.globl ClaimLock.maxcores
.globl ClaimLock.maxchanends
.globl ClaimLock.maxtimers
.set ClaimLock.nstackwords, 0
.set ClaimLock.maxcores, 1
.set ClaimLock.maxchanends, 0
.set ClaimLock.maxtimers, 0
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// void FreeLock(lock l) // void FreeLock(lock l)
.extern FreeLock
.globl FreeLock.nstackwords
.linkset FreeLock.nstackwords, 0
.globl FreeLock .globl FreeLock
.text .cc_top FreeLock.function
.align 2
FreeLock: FreeLock:
out res[r0], r0 out res[r0], r0
retsp 0 retsp 0
.size FreeLock, .-FreeLock
.cc_bottom FreeLock.function
.globl FreeLock.nstackwords
.globl FreeLock.maxcores
.globl FreeLock.maxchanends
.globl FreeLock.maxtimers
.set FreeLock.nstackwords, 0
.set FreeLock.maxcores, 1
.set FreeLock.maxchanends, 0
.set FreeLock.maxtimers, 0
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// void FreeLockResource(lock l) // void FreeLockResource(lock l)
.extern FreeLockResource
.globl FreeLockResource.nstackwords
.linkset FreeLockResource.nstackwords, 0
.globl FreeLockResource .globl FreeLockResource
.text .cc_top FreeLockResource.function
.align 2
FreeLockResource: FreeLockResource:
freer res[r0] freer res[r0]
retsp 0 retsp 0
.size FreeLockResource, .-FreeLockResource
.cc_bottom FreeLockResource.function
.globl FreeLockResource.nstackwords
.globl FreeLockResource.maxcores
.globl FreeLockResource.maxchanends
.globl FreeLockResource.maxtimers
.set FreeLockResource.nstackwords, 0
.set FreeLockResource.maxcores, 1
.set FreeLockResource.maxchanends, 0
.set FreeLockResource.maxtimers, 0

View File

@@ -3,7 +3,6 @@
* @brief Top level for XMOS USB 2.0 Audio 2.0 Reference Designs. * @brief Top level for XMOS USB 2.0 Audio 2.0 Reference Designs.
* @author Ross Owen, XMOS Semiconductor Ltd * @author Ross Owen, XMOS Semiconductor Ltd
*/ */
#include <syscall.h> #include <syscall.h>
#include <platform.h> #include <platform.h>
#include <xs1.h> #include <xs1.h>
@@ -29,11 +28,19 @@
#include "iap.h" #include "iap.h"
#endif #endif
#ifdef MIXER
#include "mixer.h"
#endif
#ifndef AUDIO_IO_TILE #ifndef AUDIO_IO_TILE
#define AUDIO_IO_TILE 0 #define AUDIO_IO_TILE 0
#endif #endif
/* Audio I/O */ #ifndef XUD_TILE
#define XUD_TILE 0
#endif
/* Audio I/O - Port declarations */
#if I2S_WIRES_DAC > 0 #if I2S_WIRES_DAC > 0
on tile[AUDIO_IO_TILE] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] = on tile[AUDIO_IO_TILE] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] =
{PORT_I2S_DAC0, {PORT_I2S_DAC0,
@@ -102,7 +109,7 @@ on tile[AUDIO_IO_TILE] : in port p_bclk = PORT_I2S_BCLK;
#endif #endif
on tile[AUDIO_IO_TILE] : port p_mclk_in = PORT_MCLK_IN; on tile[AUDIO_IO_TILE] : port p_mclk_in = PORT_MCLK_IN;
on tile[0] : in port p_for_mclk_count = PORT_MCLK_COUNT; on tile[XUD_TILE] : in port p_for_mclk_count = PORT_MCLK_COUNT;
#ifdef SPDIF #ifdef SPDIF
on tile[AUDIO_IO_TILE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT; on tile[AUDIO_IO_TILE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT;
@@ -110,7 +117,7 @@ on tile[AUDIO_IO_TILE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT;
#ifdef MIDI #ifdef MIDI
on tile[AUDIO_IO_TILE] : port p_midi_tx = PORT_MIDI_OUT; on tile[AUDIO_IO_TILE] : port p_midi_tx = PORT_MIDI_OUT;
on tile[AUDIO_IO_TILE] : port p_midi_rx = PORT_MIDI_IN; on tile[AUDIO_IO_TILE] : buffered port:1 p_midi_rx = PORT_MIDI_IN;
#endif #endif
/* Clock blocks */ /* Clock blocks */
@@ -119,9 +126,9 @@ on tile[AUDIO_IO_TILE] : clock clk_midi = XS1_CLKBLK_REF;
#endif #endif
on tile[AUDIO_IO_TILE] : clock clk_audio_mclk = XS1_CLKBLK_2; /* Master clock */ on tile[AUDIO_IO_TILE] : clock clk_audio_mclk = XS1_CLKBLK_2; /* Master clock */
#if(AUDIO_IO_TILE != 0) #if(AUDIO_IO_TILE != XUD_TILE)
on tile[0] : clock clk_audio_mclk2 = XS1_CLKBLK_2; /* Master clock */ on tile[XUD_TILE] : clock clk_audio_mclk2 = XS1_CLKBLK_2; /* Master clock */
on tile[0] : in port p_mclk_in2 = PORT_MCLK_IN2; on tile[XUD_TILE] : in port p_mclk_in2 = PORT_MCLK_IN2;
#endif #endif
@@ -131,16 +138,18 @@ on tile[AUDIO_IO_TILE] : clock clk_mst_spd = XS1_CLKBLK_1;
#endif #endif
/* L Series needs a port to use for USB reset */ /* L Series needs a port to use for USB reset */
#ifdef ARCH_L #if (defined(ARCH_L) || defined(ARCH_G)) && defined(PORT_USB_RESET)
#ifdef PORT_USB_RESET
/* This define is checked since it could be on a shift reg or similar */ /* This define is checked since it could be on a shift reg or similar */
on tile[0] : out port p_usb_rst = PORT_USB_RESET; on tile[XUD_TILE] : out port p_usb_rst = PORT_USB_RESET;
#endif
/* L Series also needs a clock for this port */
on tile[0] : clock clk = XS1_CLKBLK_4;
#else #else
/* Reset port not required for SU1 due to built in Phy */ /* Reset port not required for U series due to built in Phy */
#define p_usb_rst null #define p_usb_rst null
#endif
#if defined (ARCH_L) || defined(ARCH_G)
/* L Series also needs a clock for this port */
on tile[XUD_TILE] : clock clk = XS1_CLKBLK_4;
#else
#define clk null #define clk null
#endif #endif
@@ -149,6 +158,7 @@ on tile [AUDIO_IO_TILE] : port p_i2c_sda = PORT_I2C_SDA;
on tile [AUDIO_IO_TILE] : port p_i2c_scl = PORT_I2C_SCL; on tile [AUDIO_IO_TILE] : port p_i2c_scl = PORT_I2C_SCL;
#endif #endif
/* Endpoint type tables for XUD */ /* Endpoint type tables for XUD */
XUD_EpType epTypeTableOut[EP_CNT_OUT] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, XUD_EpType epTypeTableOut[EP_CNT_OUT] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE,
XUD_EPTYPE_ISO, /* Audio */ XUD_EPTYPE_ISO, /* Audio */
@@ -178,6 +188,7 @@ XUD_EpType epTypeTableIn[EP_CNT_IN] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE,
#endif #endif
}; };
void thread_speed() void thread_speed()
{ {
#ifdef FAST_MODE #ifdef FAST_MODE
@@ -203,63 +214,58 @@ void xscope_user_init()
#define pwrConfig XUD_PWR_BUS #define pwrConfig XUD_PWR_BUS
#endif #endif
/* Core USB Audio functions - must be called on the Tile connected to the USB Phy */
int main() void usb_audio_core(chanend c_mix_out
#ifdef MIDI
, chanend c_midi
#endif
#ifdef IAP
, chanend c_iap
#endif
#ifdef MIXER
, chanend c_mix_ctl
#endif
)
{ {
chan c_sof; chan c_sof;
chan c_xud_out[EP_CNT_OUT]; /* Endpoint channels for XUD */ chan c_xud_out[EP_CNT_OUT]; /* Endpoint channels for XUD */
chan c_xud_in[EP_CNT_IN]; chan c_xud_in[EP_CNT_IN];
chan c_aud_ctl; chan c_aud_ctl;
chan c_mix_out;
#ifdef MIDI
chan c_midi;
#endif
#ifdef IAP
chan c_iap;
#endif
#ifdef TEST_MODE_SUPPORT #ifdef TEST_MODE_SUPPORT
#warning Building with test mode support #warning Building with test mode support
chan c_usb_test; chan c_usb_test;
#else #else
#define c_usb_test null #define c_usb_test null
#endif #endif
#ifdef SU1_ADC_ENABLE
chan c_adc;
#else
#define c_adc null
#endif
#ifdef CHAN_BUFF_CTRL #ifdef CHAN_BUFF_CTRL
#warning Using channel to control buffering - this may reduce performance but improve power consumption #warning Using channel to control buffering - this may reduce performance but improve power consumption
chan c_buff_ctrl; chan c_buff_ctrl;
#endif #endif
#ifndef MIXER
#define c_mix_ctl null
#endif
par par
{ {
/* USB Interface Core */
/* USB Interface */
#if (AUDIO_CLASS==2) #if (AUDIO_CLASS==2)
on tile[0]: XUD_Manager(c_xud_out, EP_CNT_OUT, c_xud_in, EP_CNT_IN, XUD_Manager(c_xud_out, EP_CNT_OUT, c_xud_in, EP_CNT_IN,
c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst, c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst,
clk, 1, XUD_SPEED_HS, c_usb_test, pwrConfig); clk, 1, XUD_SPEED_HS, c_usb_test, pwrConfig);
#else #else
on tile[0]:XUD_Manager(c_xud_out, EP_CNT_OUT, c_xud_in, EP_CNT_IN, XUD_Manager(c_xud_out, EP_CNT_OUT, c_xud_in, EP_CNT_IN,
c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst, c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst,
clk, 1, XUD_SPEED_FS, c_usb_test, pwrConfig); clk, 1, XUD_SPEED_FS, c_usb_test, pwrConfig);
#endif #endif
on tile[0]: /* USB Packet buffering Core */
{ {
unsigned x;
thread_speed(); thread_speed();
/* Attach mclk count port to mclk clock-block (for feedback) */ /* Attach mclk count port to mclk clock-block (for feedback) */
//set_port_clock(p_for_mclk_count, clk_audio_mclk); //set_port_clock(p_for_mclk_count, clk_audio_mclk);
{
unsigned x;
#if(AUDIO_IO_TILE != 0) #if(AUDIO_IO_TILE != 0)
set_clock_src(clk_audio_mclk2, p_mclk_in2); set_clock_src(clk_audio_mclk2, p_mclk_in2);
set_port_clock(p_for_mclk_count, clk_audio_mclk2); set_port_clock(p_for_mclk_count, clk_audio_mclk2);
@@ -269,8 +275,6 @@ int main()
asm("ldw %0, dp[clk_audio_mclk]":"=r"(x)); asm("ldw %0, dp[clk_audio_mclk]":"=r"(x));
asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x)); asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x));
#endif #endif
}
buffer(c_xud_out[EP_NUM_OUT_AUD],/* Audio Out*/ buffer(c_xud_out[EP_NUM_OUT_AUD],/* Audio Out*/
c_xud_in[EP_NUM_IN_AUD], /* Audio In */ c_xud_in[EP_NUM_IN_AUD], /* Audio In */
c_xud_in[EP_NUM_IN_FB], /* Audio FB */ c_xud_in[EP_NUM_IN_FB], /* Audio FB */
@@ -293,20 +297,16 @@ int main()
#ifdef CHAN_BUFF_CTRL #ifdef CHAN_BUFF_CTRL
, c_buff_ctrl , c_buff_ctrl
#endif #endif
); );
} }
on tile[AUDIO_IO_TILE]: /* Endpoint 0 Core */
{ {
thread_speed(); thread_speed();
Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, null, c_usb_test);
/* Audio I/O (pars additional S/PDIF TX thread) */
audio(c_mix_out, null, null, c_adc);
} }
on tile[0]: /* Decoupling core */
{ {
thread_speed(); thread_speed();
decouple(c_mix_out, null decouple(c_mix_out, null
@@ -315,35 +315,125 @@ int main()
#endif #endif
); );
} }
}
/* Endpoint 0 */
on tile[0]:
{
thread_speed();
Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, null, null, c_usb_test);
} }
void usb_audio_io(chanend c_aud_in, chanend ?c_adc
#ifdef MIDI
, chanend c_midi
#endif
#ifdef IAP
, chanend c_iap
#endif
#ifdef MIXER
, chanend c_mix_ctl
#endif
)
{
chan c_mix_out;
par
{
#ifdef MIXER
/* Mixer cores(s) */
{
thread_speed();
mixer(c_aud_in, c_mix_out, c_mix_ctl);
}
#endif
/* Audio I/O Core (pars additional S/PDIF TX Core) */
{
thread_speed();
#ifdef MIXER
audio(c_mix_out, null, null, c_adc);
#else
audio(c_aud_in, null, null, c_adc);
#endif
}
/* MIDI/iAP Core */
#if defined (MIDI) || defined IAP #if defined (MIDI) || defined IAP
on tile[AUDIO_IO_TILE]:
{ {
thread_speed(); thread_speed();
#ifdef MIDI #ifdef MIDI
usb_midi(p_midi_rx, p_midi_tx, clk_midi, c_midi, 0, null, null, null, null); usb_midi(p_midi_rx, p_midi_tx, clk_midi, c_midi, 0, null, null, null, null);
#else #else
iAP(c_iap, null, i2cPorts.scl, i2cPorts.sda); iAP(c_iap, null, null, null);
#endif #endif
} }
#endif #endif
}
}
#ifndef USER_MAIN_DECLARATIONS
#define USER_MAIN_DECLARATIONS
#endif
#ifndef USER_MAIN_CORES
#define USER_MAIN_CORES
#endif
/* Main for USB Audio Applications */
int main()
{
chan c_mix_out;
#ifdef MIDI
chan c_midi;
#else
#define c_midi null
#endif
#ifdef IAP
chan c_iap;
#endif
#ifdef SU1_ADC_ENABLE
chan c_adc;
#else
#define c_adc null
#endif
#ifdef MIXER
chan c_mix_ctl;
#endif
USER_MAIN_DECLARATIONS
par
{
on tile[XUD_TILE]: usb_audio_core(c_mix_out
#ifdef MIDI
, c_midi
#endif
#ifdef IAP
, c_iap
#endif
#ifdef MIXER
, c_mix_ctl
#endif
);
on tile[AUDIO_IO_TILE]: usb_audio_io(c_mix_out, c_adc
#ifdef MIDI
, c_midi
#endif
#ifdef IAP
, c_iap
#endif
#ifdef MIXER
, c_mix_ctl
#endif
);
USER_MAIN_CORES
}
#ifdef SU1_ADC_ENABLE #ifdef SU1_ADC_ENABLE
xs1_su_adc_service(c_adc); xs1_su_adc_service(c_adc);
#endif #endif
}
return 0; return 0;
} }

View File

@@ -9,6 +9,7 @@
.cc_top doMix##i.function,doMix##i; \ .cc_top doMix##i.function,doMix##i; \
.align 4 ;\ .align 4 ;\
.globl doMix##i ;\ .globl doMix##i ;\
.type doMix##i, @function ;\
.globl doMix##i##.nstackwords ;\ .globl doMix##i##.nstackwords ;\
.globl doMix##i##.maxthreads ; \ .globl doMix##i##.maxthreads ; \
.globl doMix##i##.maxtimers ; \ .globl doMix##i##.maxtimers ; \
@@ -42,6 +43,7 @@ doMix##i##: ;\
retsp 0x0;\ retsp 0x0;\
\ \
\ \
.size doMix##i, .-doMix##i; \
.cc_bottom doMix##i##.function; .cc_bottom doMix##i##.function;
#define N MIX_INPUTS #define N MIX_INPUTS
@@ -125,8 +127,9 @@ DOMIX_BOT(7)
#define N MAX_MIX_COUNT #define N MAX_MIX_COUNT
.cc_top setPtr.function,setPtr; .cc_top setPtr.function,setPtr;
.align 4 ; .align 4 ;
.globl setPtr.nstackwords;
.globl setPtr; .globl setPtr;
.type setPtr, @function
.globl setPtr.nstackwords;
.globl setPtr.maxthreads; .globl setPtr.maxthreads;
.globl setPtr.maxtimers; .globl setPtr.maxtimers;
.globl setPtr.maxchanends; .globl setPtr.maxchanends;
@@ -151,14 +154,20 @@ setPtr_go:
add r1, r1, r2; add r1, r1, r2;
st8 r1, r11[r0]; st8 r1, r11[r0];
retsp 0; retsp 0;
.size setPtr, .-setPtr
.cc_bottom setPtr.function .cc_bottom setPtr.function
.section .cp.const4, "acM", @progbits, 4 .section .cp.const4, "acM", @progbits, 4
.LC0: .cc_top .LC0.data
.align 4 .align 4
.LC0:
.int 0x7fffff00 .int 0x7fffff00
.cc_bottom .LC0.data
.cc_top .LC1.data
.align 4
.LC1: .LC1:
.int 0x80000000 .int 0x80000000
.cc_bottom .LC1.data
#undef N #undef N
#undef BODY #undef BODY

View File

@@ -1,7 +1,6 @@
#include <xs1.h> #include <xs1.h>
#include <print.h>
#include "mixer.h" #include "mixer.h"
#include "devicedefines.h" #include "devicedefines.h"
#include "xc_ptr.h" #include "xc_ptr.h"
@@ -115,7 +114,7 @@ int doMix8(xc_ptr samples, xc_ptr mult);
/* DO NOT inline, causes 10.4.2 tools to add extra loads in loop */ /* DO NOT inline, causes 10.4.2 tools to add extra loads in loop */
/* At 18 x 12dB we could get 64 x bigger */ /* At 18 x 12dB we could get 64 x bigger */
#pragma unsafe arrays #pragma unsafe arrays
int doMix(xc_ptr samples, xc_ptr ptr, xc_ptr mult) static int doMix(xc_ptr samples, xc_ptr ptr, xc_ptr mult)
{ {
int h=0; int h=0;
int l=0; int l=0;
@@ -151,7 +150,7 @@ int doMix(xc_ptr samples, xc_ptr ptr, xc_ptr mult)
#endif #endif
#pragma unsafe arrays #pragma unsafe arrays
void giveSamplesToHost(chanend c, xc_ptr samples, xc_ptr ptr, xc_ptr multIn) static void giveSamplesToHost(chanend c, xc_ptr samples, xc_ptr ptr, xc_ptr multIn)
{ {
#if defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX) #if defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX)
int mult; int mult;
@@ -184,7 +183,9 @@ void giveSamplesToHost(chanend c, xc_ptr samples, xc_ptr ptr, xc_ptr multIn)
} }
#pragma unsafe arrays #pragma unsafe arrays
static void getSamplesFromHost(chanend c, xc_ptr samples, int base) static void getSamplesFromHost(chanend c, xc_ptr samples, int base, unsigned underflow)
{
if(!underflow)
{ {
#pragma loop unroll #pragma loop unroll
for (int i=0;i<NUM_USB_CHAN_OUT;i++) for (int i=0;i<NUM_USB_CHAN_OUT;i++)
@@ -216,11 +217,16 @@ static void getSamplesFromHost(chanend c, xc_ptr samples, int base)
#else #else
write_via_xc_ptr_indexed(samples,base+i,sample); write_via_xc_ptr_indexed(samples,base+i,sample);
#endif #endif
} } }
} }
#pragma unsafe arrays #pragma unsafe arrays
void giveSamplesToDevice(chanend c, xc_ptr samples, xc_ptr ptr, xc_ptr multOut) static void giveSamplesToDevice(chanend c, xc_ptr samples, xc_ptr ptr, xc_ptr multOut, unsigned underflow)
{
outuint(c, underflow);
if(!underflow)
{ {
#pragma loop unroll #pragma loop unroll
for (int i=0;i<NUM_USB_CHAN_OUT;i++) for (int i=0;i<NUM_USB_CHAN_OUT;i++)
@@ -246,9 +252,10 @@ void giveSamplesToDevice(chanend c, xc_ptr samples, xc_ptr ptr, xc_ptr multOut)
#endif #endif
} }
} }
}
#pragma unsafe arrays #pragma unsafe arrays
void getSamplesFromDevice(chanend c, xc_ptr samples, int base) static void getSamplesFromDevice(chanend c, xc_ptr samples, int base)
{ {
#if defined(IN_VOLUME_IN_MIXER) && !defined(IN_VOLUME_AFTER_MIX) #if defined(IN_VOLUME_IN_MIXER) && !defined(IN_VOLUME_AFTER_MIX)
int mult; int mult;
@@ -281,18 +288,18 @@ void getSamplesFromDevice(chanend c, xc_ptr samples, int base)
} }
} }
int mixer1_mix2_flag = (DEFAULT_FREQ > 96000); static int mixer1_mix2_flag = (DEFAULT_FREQ > 96000);
#pragma unsafe arrays #pragma unsafe arrays
void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
{ {
int mixed; int mixed;
unsigned cmd; unsigned cmd;
while (1) while (1)
{ {
#pragma xta endpoint "mixer1_req" #pragma xta endpoint "mixer1_req"
/* Request from audio() */
inuint(c_mixer2); inuint(c_mixer2);
/* Request data from decouple thread */ /* Request data from decouple thread */
@@ -424,12 +431,10 @@ void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
#pragma loop unroll #pragma loop unroll
for (int i=0;i<MAX_MIX_COUNT;i++) for (int i=0;i<MAX_MIX_COUNT;i++)
{ {
write_via_xc_ptr_indexed(samples, write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + i), 0);
(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + i),
0);
} }
/* Inform mixer 2 about freq change */ /* Inform mixer2 (or audio())about freq change */
outct(c_mixer2, XS1_CT_END); outct(c_mixer2, XS1_CT_END);
outuint(c_mixer2, sampFreq); outuint(c_mixer2, sampFreq);
@@ -439,7 +444,7 @@ void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
} }
else else
{ {
inuint(c_host); unsigned underflow = inuint(c_host);
#if MAX_MIX_COUNT > 0 #if MAX_MIX_COUNT > 0
outuint(c_mixer2, 0); outuint(c_mixer2, 0);
giveSamplesToHost(c_host, samples, samples_to_host_map, multIn); giveSamplesToHost(c_host, samples, samples_to_host_map, multIn);
@@ -506,19 +511,20 @@ void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
} }
#else /* IF MAX_MIX_COUNT > 0 */ #else /* IF MAX_MIX_COUNT > 0 */
/* No mixes, this thread runs on its own doing just volume */ /* No mixes, this thread runs on its own doing just volume */
giveSamplesToDevice(c_mixer2, samples, samples_to_device_map, multOut); giveSamplesToDevice(c_mixer2, samples, samples_to_device_map, multOut, underflow);
getSamplesFromDevice(c_mixer2, samples, NUM_USB_CHAN_OUT); getSamplesFromDevice(c_mixer2, samples, NUM_USB_CHAN_OUT);
giveSamplesToHost(c_host, samples, samples_to_host_map, multIn); giveSamplesToHost(c_host, samples, samples_to_host_map, multIn);
getSamplesFromHost(c_host, samples, 0); getSamplesFromHost(c_host, samples, 0, underflow);
#endif #endif
} }
} }
} }
int mixer2_mix2_flag = (DEFAULT_FREQ > 96000); static int mixer2_mix2_flag = (DEFAULT_FREQ > 96000);
#if (MAX_MIX_COUNT > 0)
#pragma unsafe arrays #pragma unsafe arrays
void mixer2(chanend c_mixer1, chanend c_audio) static void mixer2(chanend c_mixer1, chanend c_audio)
{ {
int mixed; int mixed;
@@ -622,6 +628,7 @@ void mixer2(chanend c_mixer1, chanend c_audio)
} }
} }
} }
#endif
void mixer(chanend c_mix_in, chanend c_mix_out, chanend c_mix_ctl) void mixer(chanend c_mix_in, chanend c_mix_out, chanend c_mix_ctl)
{ {
@@ -651,11 +658,8 @@ void mixer(chanend c_mix_in, chanend c_mix_out, chanend c_mix_ctl)
int num_mixes = DEFAULT_FREQ > 96000 ? 2 : MAX_MIX_COUNT; int num_mixes = DEFAULT_FREQ > 96000 ? 2 : MAX_MIX_COUNT;
for (int i=0;i<NUM_USB_CHAN_OUT;i++) for (int i=0;i<NUM_USB_CHAN_OUT;i++)
{ {
//samples_to_device_map_array[i] = i;
asm("stw %0, %1[%2]":: asm("stw %0, %1[%2]":: "r"(i), "r"(samples_to_device_map), "r"(i));
"r"(i),
"r"(samples_to_device_map),
"r"(i));
} }
} }

View File

@@ -5,6 +5,7 @@
#include <xs1_l_registers.h> #include <xs1_l_registers.h>
#include <xs1_su_registers.h> #include <xs1_su_registers.h>
#include <platform.h> #include <platform.h>
#include <hwtimer.h>
#ifndef VOLTAGE_REDUCTION_mV #ifndef VOLTAGE_REDUCTION_mV
#define VOLTAGE_REDUCTION_mV 20 #define VOLTAGE_REDUCTION_mV 20
@@ -25,7 +26,7 @@ void archU_powerSaving()
// Reduce the VDDCORE voltage level // Reduce the VDDCORE voltage level
for (unsigned count=0; count < (VOLTAGE_REDUCTION_mV/10); count++) for (unsigned count=0; count < (VOLTAGE_REDUCTION_mV/10); count++)
{ {
timer t; hwtimer_t t;
int time; int time;
writeval[0] = (ARCH_U_VOLTAGE_FIRST_STEP - count); writeval[0] = (ARCH_U_VOLTAGE_FIRST_STEP - count);

View File

@@ -98,9 +98,11 @@ unsigned packState = 0;
unsigned packData = 0; unsigned packData = 0;
#if (AUDIO_CLASS==2) #if (AUDIO_CLASS==2)
int slotSize = 4; /* 4 bytes per ssample for Audio Class 2.0 */ int g_slotSize = SAMPLE_SUBSLOT_SIZE_HS; /* 4 bytes per ssample for Audio Class 2.0 */
int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_CLASS_TWO;
#else #else
int slotSize = 3; /* 3 bytes per sample for Audio Class 1.0 */ int g_slotSize = SAMPLE_SUBSLOT_SIZE_FS; /* 3 bytes per sample for Audio Class 1.0 */
int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_CLASS_ONE;
#endif #endif
#pragma select handler #pragma select handler
@@ -123,11 +125,13 @@ void handle_audio_request(chanend c_mix_out)
#if defined(AUDIO_CLASS_FALLBACK) || defined (FULL_SPEED_AUDIO_2) #if defined(AUDIO_CLASS_FALLBACK) || defined (FULL_SPEED_AUDIO_2)
if (usb_speed == XUD_SPEED_HS) if (usb_speed == XUD_SPEED_HS)
{ {
slotSize = 4; /* 4 bytes per sample */ g_slotSize = SAMPLE_SUBSLOT_SIZE_HS; /* Typically 4 bytes per sample for HS */
g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_CLASS_TWO;
} }
else else
{ {
slotSize = 3; /* 3 bytes per sample */ g_slotSize = SAMPLE_SUBSLOT_SIZE_FS; /* Typically 3 bytes per sample for FS */
g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_CLASS_ONE;
} }
#endif #endif
@@ -156,9 +160,15 @@ void handle_audio_request(chanend c_mix_out)
} }
else else
{ {
/* Not in overflow, store samples from mixer into sample buffer */ /* Not in overflow, store samples from mixer into sample buffer */
if (usb_speed == XUD_SPEED_HS) switch(g_slotSize)
{ {
case 4:
{
#if (SAMPLE_SUBSLOT_SIZE_HS != 4) && (SAMPLE_SUBSLOT_SIZE_FS != 4)
__builtin_unreachable();
#endif
unsigned ptr = g_aud_to_host_dptr; unsigned ptr = g_aud_to_host_dptr;
for(int i = 0; i < g_numUsbChanIn; i++) for(int i = 0; i < g_numUsbChanIn; i++)
@@ -184,9 +194,13 @@ void handle_audio_request(chanend c_mix_out)
/* Update global pointer */ /* Update global pointer */
g_aud_to_host_dptr = ptr; g_aud_to_host_dptr = ptr;
break;
} }
else
{ 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 */ /* Receive sample */
@@ -207,7 +221,7 @@ void handle_audio_request(chanend c_mix_out)
packData = sample; packData = sample;
break; break;
case 1: case 1:
packData = packData >> 8 | ((sample & 0xff00)<<16); 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; 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);
@@ -227,6 +241,49 @@ void handle_audio_request(chanend c_mix_out)
} }
packState++; packState++;
} }
break;
case 2:
#if (SAMPLE_SUBSLOT_SIZE_HS != 2) && (SAMPLE_SUBSLOT_SIZE_FS != 2)
__builtin_unreachable();
#endif
for(int i = 0; i < g_numUsbChanIn; i++)
{
/* Receive sample */
int sample = inuint(c_mix_out);
#if !defined(IN_VOLUME_IN_MIXER)
/* Apply volume */
int mult;
int h;
unsigned l;
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
sample = h << 3;
#if (SAMPLE_BIT_RESOLUTION_HS > 24) || (SAMPLE_BIT_RESOLUTION_FS > 24)
sample |= (l >> 29) & 0x7; // Note, this step is not required if we assume sample depth is 24 (rather than 32)
#endif
#elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX)
sample = sample << 3;
#endif
/* Write into fifo */
switch (packState&0x1)
{
case 0:
packData = sample;
break;
case 1:
packData = (packData>>16) | (sample & 0xffff0000);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
break;
}
}
break;
default:
__builtin_unreachable();
break;
} }
/* Input any remaining channels - past this thread we always operate on max channel count */ /* Input any remaining channels - past this thread we always operate on max channel count */
@@ -273,8 +330,12 @@ void handle_audio_request(chanend c_mix_out)
} }
else else
{ {
if (usb_speed == XUD_SPEED_HS) switch(g_slotSize)
{ {
case 4:
#if (SAMPLE_SUBSLOT_SIZE_HS != 4) && (SAMPLE_SUBSLOT_SIZE_FS != 4)
__builtin_unreachable();
#endif
/* 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++)
{ {
@@ -291,15 +352,21 @@ void handle_audio_request(chanend c_mix_out)
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);
h <<= 3; h <<= 3;
#if (SAMPLE_BIT_RESOLUTION_HS > 24) || (SAMPLE_BIT_RESOLUTION_FS > 24)
h |= (l >>29)& 0x7; // Note this step is not required if we assume sample depth is 24bit (rather than 32bit) h |= (l >>29)& 0x7; // Note this step is not required if we assume sample depth is 24bit (rather than 32bit)
#endif
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 break;
{
case 3:
#if (SAMPLE_SUBSLOT_SIZE_HS != 3) && (SAMPLE_SUBSLOT_SIZE_FS != 3)
__builtin_unreachable();
#endif
/* 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++)
{ {
@@ -345,7 +412,50 @@ void handle_audio_request(chanend c_mix_out)
#endif #endif
} }
break;
case 2:
#if (SAMPLE_SUBSLOT_SIZE_HS != 3) && (SAMPLE_SUBSLOT_SIZE_FS != 3)
__builtin_unreachable();
#endif
/* Buffering not underflow condition send out some samples...*/
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;
break;
case 1:
g_aud_from_host_rdptr+=4;
sample = unpackData & 0xffff0000;
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);
h <<= 3;
outuint(c_mix_out, h);
#else
outuint(c_mix_out, sample);
#endif
}
break;
default:
__builtin_unreachable();
break;
} /* switch(g_slotsize) */
/* Output remaining channels. Past this point we always operate on MAX chan count */ /* Output remaining channels. Past this point we always operate on MAX chan count */
for(int i = 0; i < NUM_USB_CHAN_OUT - g_numUsbChanOut; i++) for(int i = 0; i < NUM_USB_CHAN_OUT - g_numUsbChanOut; i++)
@@ -354,7 +464,7 @@ void handle_audio_request(chanend c_mix_out)
} }
/* 3/4 bytes per sample */ /* 3/4 bytes per sample */
aud_data_remaining_to_device -= (g_numUsbChanOut*slotSize); aud_data_remaining_to_device -= (g_numUsbChanOut*g_slotSize);
} }
if (!inOverflow) if (!inOverflow)
@@ -365,16 +475,13 @@ void handle_audio_request(chanend c_mix_out)
if (totalSampsToWrite) if (totalSampsToWrite)
{ {
if (usb_speed == XUD_SPEED_HS) unsigned datasize = totalSampsToWrite * g_slotSize * g_numUsbChanIn;
{
g_aud_to_host_wrptr += 4+totalSampsToWrite*4*g_numUsbChanIn; /* Round up to nearest word - note, not needed for slotsize == 4! */
} datasize = (datasize+3) & (~0x3);
else
{
unsigned int datasize = totalSampsToWrite*3*NUM_USB_CHAN_IN_A1;
datasize = (datasize+3) & (~0x3); // round up to nearest word
g_aud_to_host_wrptr += 4+datasize; g_aud_to_host_wrptr += 4+datasize;
}
if (g_aud_to_host_wrptr >= aud_to_host_fifo_end) if (g_aud_to_host_wrptr >= aud_to_host_fifo_end)
{ {
g_aud_to_host_wrptr = aud_to_host_fifo_start; g_aud_to_host_wrptr = aud_to_host_fifo_start;
@@ -389,6 +496,7 @@ void handle_audio_request(chanend c_mix_out)
totalSampsToWrite = speedRem >> 16; totalSampsToWrite = speedRem >> 16;
speedRem &= 0xffff; 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))
@@ -403,6 +511,12 @@ void handle_audio_request(chanend c_mix_out)
totalSampsToWrite = 0; totalSampsToWrite = 0;
} }
} }
#else
if (totalSampsToWrite < 0 || totalSampsToWrite * g_slotSize * g_numUsbChanIn > g_maxPacketSize)
{
totalSampsToWrite = 0;
}
#endif
/* Calc slots left in fifo */ /* Calc slots left in fifo */
space_left = g_aud_to_host_rdptr - g_aud_to_host_wrptr; space_left = g_aud_to_host_rdptr - g_aud_to_host_wrptr;
@@ -418,7 +532,7 @@ void handle_audio_request(chanend c_mix_out)
/* Packet okay, write to fifo */ /* Packet okay, write to fifo */
if (totalSampsToWrite) if (totalSampsToWrite)
{ {
write_via_xc_ptr(g_aud_to_host_wrptr, totalSampsToWrite*slotSize*g_numUsbChanIn); write_via_xc_ptr(g_aud_to_host_wrptr, totalSampsToWrite*g_slotSize*g_numUsbChanIn);
packState = 0; packState = 0;
g_aud_to_host_dptr = g_aud_to_host_wrptr + 4; g_aud_to_host_dptr = g_aud_to_host_wrptr + 4;
} }
@@ -432,7 +546,7 @@ void handle_audio_request(chanend c_mix_out)
} }
} }
if (!outUnderflow && (aud_data_remaining_to_device<(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 */ /* 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)
@@ -472,7 +586,7 @@ unsigned g_intFlag = 0;
extern unsigned char g_intData[8]; extern unsigned char g_intData[8];
void check_for_interrupt(chanend ?c_clk_int) { static void check_for_interrupt(chanend ?c_clk_int) {
unsigned tmp; unsigned tmp;
select select
@@ -831,7 +945,7 @@ void decouple(chanend c_mix_out,
read_via_xc_ptr(datalength, released_buffer); read_via_xc_ptr(datalength, released_buffer);
/* Ignore bad small packets */ /* Ignore bad small packets */
if ((datalength >= (g_numUsbChanOut * slotSize)) && (released_buffer == aud_from_host_wrptr)) 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 */ /* Move the write pointer of the fifo on - round up to nearest word */

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
#include "usb_midi.h" #include "usb_midi.h"
#endif #endif
#ifdef IAP #ifdef IAP
#include "iAP.h" #include "iap.h"
#endif #endif
#include "xc_ptr.h" #include "xc_ptr.h"
#include "commands.h" #include "commands.h"
@@ -54,9 +54,9 @@ static inline void swap(xc_ptr &a, xc_ptr &b)
#endif #endif
#ifdef MIDI #ifdef MIDI
unsigned int g_midi_to_host_buffer_A[MAX_USB_MIDI_PACKET_SIZE/4+4]; static unsigned int g_midi_to_host_buffer_A[MIDI_USB_BUFFER_TO_HOST_SIZE/4];
unsigned int g_midi_to_host_buffer_B[MAX_USB_MIDI_PACKET_SIZE/4+4]; static unsigned int g_midi_to_host_buffer_B[MIDI_USB_BUFFER_TO_HOST_SIZE/4];
int g_midi_from_host_buffer[MAX_USB_MIDI_PACKET_SIZE/4+4]; static unsigned int g_midi_from_host_buffer[MAX_USB_MIDI_PACKET_SIZE/4];
#endif #endif
#ifdef IAP #ifdef IAP
@@ -145,15 +145,12 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
xc_ptr aud_from_host_buffer = 0; xc_ptr aud_from_host_buffer = 0;
#ifdef MIDI #ifdef MIDI
xc_ptr midi_from_host_buffer = 0; xc_ptr midi_from_host_buffer = array_to_xc_ptr(g_midi_from_host_buffer);
xc_ptr midi_to_host_buffer = 0;
xc_ptr midi_to_host_waiting_buffer = 0;
xc_ptr midi_from_host_rdptr; xc_ptr midi_from_host_rdptr;
xc_ptr midi_to_host_buffer_being_sent = array_to_xc_ptr(g_midi_to_host_buffer_A); xc_ptr midi_to_host_buffer_being_sent = array_to_xc_ptr(g_midi_to_host_buffer_A);
xc_ptr midi_to_host_buffer_being_collected = array_to_xc_ptr(g_midi_to_host_buffer_B); xc_ptr midi_to_host_buffer_being_collected = array_to_xc_ptr(g_midi_to_host_buffer_B);
int is_ack; int is_ack;
unsigned int datum; unsigned int datum;
int midi_data_remaining_to_device = 0; int midi_data_remaining_to_device = 0;
@@ -216,15 +213,6 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
} }
#ifdef MIDI
// get the two buffers to use for midi device->host
asm("ldaw %0, dp[g_midi_to_host_buffer_A]":"=r"(midi_to_host_buffer));
asm("ldaw %0, dp[g_midi_to_host_buffer_B]":"=r"(midi_to_host_waiting_buffer));
asm("ldaw %0, dp[g_midi_from_host_buffer]":"=r"(midi_from_host_buffer));
swap(midi_to_host_buffer, midi_to_host_waiting_buffer);
#endif
#ifdef OUTPUT #ifdef OUTPUT
SET_SHARED_GLOBAL(g_aud_from_host_flag, 1); SET_SHARED_GLOBAL(g_aud_from_host_flag, 1);
#endif #endif
@@ -520,19 +508,14 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
case XUD_SetData_Select(c_midi_to_host, ep_midi_to_host, tmp): case XUD_SetData_Select(c_midi_to_host, ep_midi_to_host, tmp):
asm("#midi d->h"); asm("#midi d->h");
swap(midi_to_host_buffer, midi_to_host_waiting_buffer);
/* The buffer has been sent to the host, so we can ack the midi thread */ /* 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)
{ {
/* We have some more data to send set the amount of data to send */
write_via_xc_ptr(midi_to_host_buffer_being_collected, midi_data_collected_from_device);
/* Swap the collecting and sending buffer */ /* Swap the collecting and sending buffer */
swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent); swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent);
/* Request to send packet */ /* Request to send packet */
XUD_SetReady_InPtr(ep_midi_to_host, midi_to_host_buffer_being_sent+4, midi_data_collected_from_device); 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 */ /* Mark as waiting for host to poll us */
midi_waiting_on_send_to_host = 1; midi_waiting_on_send_to_host = 1;
@@ -630,7 +613,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
if (midi_data_collected_from_device < MIDI_USB_BUFFER_TO_HOST_SIZE) if (midi_data_collected_from_device < MIDI_USB_BUFFER_TO_HOST_SIZE)
{ {
/* There is room in the collecting buffer for the data */ /* There is room in the collecting buffer for the data */
xc_ptr p = (midi_to_host_buffer_being_collected + 4) + midi_data_collected_from_device; xc_ptr p = midi_to_host_buffer_being_collected + midi_data_collected_from_device;
// Add data to the buffer // Add data to the buffer
write_via_xc_ptr(p, datum); write_via_xc_ptr(p, datum);
midi_data_collected_from_device += 4; midi_data_collected_from_device += 4;
@@ -643,12 +626,10 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
// If we are not sending data to the host then initiate it // 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)
{ {
write_via_xc_ptr(midi_to_host_buffer_being_collected, midi_data_collected_from_device);
swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent); swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent);
// Signal other side to swap // Signal other side to swap
XUD_SetReady_InPtr(ep_midi_to_host, midi_to_host_buffer_being_sent+4, midi_data_collected_from_device); 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_data_collected_from_device = 0;
midi_waiting_on_send_to_host = 1; midi_waiting_on_send_to_host = 1;
} }

View File

@@ -1,5 +1,9 @@
/* Warnings relating to defines have been moved to this XC file to avoid multiple warnings being issued from the devicedefines.h header file */ /*
Warnings relating to configuration defines located in this XC source file rather than the devicedefines.h header file in order to avoid multiple warnings being issued when the devicedefines.h header file is included in multiple files.
*/
#include "customdefines.h"
#include "customdefines.h" #include "customdefines.h"
@@ -36,7 +40,7 @@
#endif #endif
#ifndef BCD_DEVICE #ifndef BCD_DEVICE
#warning BCD_DEVICE not defined. Using 0x0620 #warning BCD_DEVICE not defined. Using XMOS release version number
#endif #endif
#if (AUDIO_CLASS==1) || defined(AUDIO_CLASS_FALLBACK) #if (AUDIO_CLASS==1) || defined(AUDIO_CLASS_FALLBACK)
@@ -54,7 +58,7 @@
#endif #endif
#ifndef AUDIO_CLASS_FALLBACK #ifndef AUDIO_CLASS_FALLBACK
#warning AUDIO_CLASS_FALLBACK not defined, using 0 #warning AUDIO_CLASS_FALLBACK not defined, using 0 (i.e. disabled)
#endif #endif

View File

@@ -1,13 +1,8 @@
#include "xs1_kernel.h" #include "xs1_kernel.h"
#include "xs1_user.h" #include "xs1_user.h"
.global write_sswitch_reg_blind, "f{si}(ui,ui,ui)" .global write_sswitch_reg_blind, "f{si}(ui,ui,ui)"
.global write_sswitch_reg_blind.nstackwords .type write_sswitch_reg_blind, @function
.linkset write_sswitch_reg_blind.nstackwords, 0
//.type read_sswitch_reg, @function
// r0 - coreid // r0 - coreid
// r1 - reg // r1 - reg
// r2 - data // r2 - data
@@ -56,4 +51,13 @@ write_sswitch_reg_blind:
write_switch_reg_fail: write_switch_reg_fail:
ldc r0, 0 ldc r0, 0
retsp 0 retsp 0
.size write_sswitch_reg_blind, .-write_sswitch_reg_blind
.cc_bottom write_sswitch_reg_blind.function .cc_bottom write_sswitch_reg_blind.function
.global write_sswitch_reg_blind.nstackwords
.global write_sswitch_reg_blind.maxchanends
.global write_sswitch_reg_blind.maxtimers
.global write_sswitch_reg_blind.maxcores
.set write_sswitch_reg_blind.nstackwords, 0
.set write_sswitch_reg_blind.maxchanends, 1
.set write_sswitch_reg_blind.maxtimers, 0
.set write_sswitch_reg_blind.maxcores, 0

View File

@@ -0,0 +1,9 @@
<Add title here>
================
:scope: <Put one of Roadmap, Example, Early Development or General Use>
:description: <Add one line here>
:keywords: <Add comma separated list of keywords>
:boards: <Add comma separated list of supported boards>
<Add description of software block>

View File

@@ -0,0 +1,9 @@
<Add title here>
================
:scope: <Put one of Roadmap, Example, Early Development or General Use>
:description: <Add one line here>
:keywords: <Add comma separated list of keywords>
:boards: <Add comma separated list of supported boards>
<Add description of software block>

View File

@@ -9,3 +9,4 @@
# #
# You can also set MODULE_XCC_C_FLAGS, MODULE_XCC_XC_FLAGS etc.. # You can also set MODULE_XCC_C_FLAGS, MODULE_XCC_XC_FLAGS etc..
DEPENDENT_MODULES = module_queue

View File

@@ -42,7 +42,7 @@ void reset_midi_state(struct midi_in_parse_state &mips) {
* @brief Construct USB MIDI event * @brief Construct USB MIDI event
* *
*/ */
unsigned makeEvent(unsigned cable_number, unsigned codeIndexNumber, unsigned midi0, unsigned midi1, unsigned midi2) { static unsigned makeEvent(unsigned cable_number, unsigned codeIndexNumber, unsigned midi0, unsigned midi1, unsigned midi2) {
unsigned event = (cable_number << 28); unsigned event = (cable_number << 28);
event |= (codeIndexNumber << 24); event |= (codeIndexNumber << 24);
event |= (midi0 << 16); event |= (midi0 << 16);

View File

@@ -1,84 +0,0 @@
#include <stdio.h>
#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;
}
}
}

View File

@@ -1,25 +0,0 @@
#ifndef QUEUE_H
#define QUEUE_H
#include <stdint.h>
#include <xccompat.h>
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

View File

@@ -15,7 +15,7 @@
* \param cable_number the cable number of the MIDI implementation. * \param cable_number the cable number of the MIDI implementation.
* This should be set to 0. * This should be set to 0.
**/ **/
void usb_midi(port ?p_midi_in, port ?p_midi_out, void usb_midi(buffered in port:1 ?p_midi_in, port ?p_midi_out,
clock ?clk_midi, clock ?clk_midi,
chanend ?c_midi, chanend ?c_midi,
unsigned cable_number, unsigned cable_number,

View File

@@ -7,8 +7,8 @@
#include "midioutparse.h" #include "midioutparse.h"
#include "queue.h" #include "queue.h"
#ifdef IAP #ifdef IAP
#include "iAP.h" #include "iap.h"
#include "iapuser.h" #include "iap_user.h"
#endif #endif
//#define MIDI_LOOPBACK 1 //#define MIDI_LOOPBACK 1
int icount = 0; int icount = 0;
@@ -22,7 +22,7 @@ static unsigned makeSymbol(unsigned data)
#define RATE 31250 #define RATE 31250
#ifndef MIDI_SHIFT_TX #ifndef MIDI_SHIFT_TX
#define MIDI_SHIFT_TX 7 #define MIDI_SHIFT_TX 0
#endif #endif
static unsigned bit_time = XS1_TIMER_MHZ * 1000000 / (unsigned) RATE; static unsigned bit_time = XS1_TIMER_MHZ * 1000000 / (unsigned) RATE;
@@ -49,7 +49,9 @@ extern unsigned polltime;
timer iAPTimer; timer iAPTimer;
#endif #endif
void usb_midi(port ?p_midi_in, port ?p_midi_out, #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
void usb_midi(buffered in port:1 ?p_midi_in, port ?p_midi_out,
clock ?clk_midi, clock ?clk_midi,
chanend ?c_midi, chanend ?c_midi,
unsigned cable_number, unsigned cable_number,
@@ -71,23 +73,23 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
timer t2; timer t2;
// One place buffer for data going out to host // One place buffer for data going out to host
queue midi_to_host_fifo; queue_t midi_to_host_fifo;
unsigned char midi_to_host_fifo_arr[4]; // Used for 32bit USB MIDI events unsigned midi_to_host_fifo_arr[1]; // Used for 32bit USB MIDI events
unsigned outputting_symbol, outputted_symbol; unsigned outputting_symbol, outputted_symbol;
struct midi_in_parse_state mips; struct midi_in_parse_state mips;
// the symbol fifo (to go out of uart) // the symbol fifo (to go out of uart)
queue symbol_fifo; queue_t symbol_fifo;
unsigned char symbol_fifo_arr[USB_MIDI_DEVICE_OUT_FIFO_SIZE * 4]; // Used for 32bit USB MIDI events unsigned symbol_fifo_arr[USB_MIDI_DEVICE_OUT_FIFO_SIZE]; // Used for 32bit USB MIDI events
unsigned rxPT, txPT; unsigned rxPT, txPT;
int midi_from_host_overflow = 0; int midi_from_host_overflow = 0;
//configure_clock_rate(clk_midi, 100, 1); //configure_clock_rate(clk_midi, 100, 1);
init_queue(symbol_fifo, symbol_fifo_arr, USB_MIDI_DEVICE_OUT_FIFO_SIZE, 4); queue_init(symbol_fifo, ARRAY_SIZE(symbol_fifo_arr));
init_queue(midi_to_host_fifo, midi_to_host_fifo_arr, 1, 4); queue_init(midi_to_host_fifo, ARRAY_SIZE(midi_to_host_fifo_arr));
configure_out_port(p_midi_out, clk_midi, 1<<MIDI_SHIFT_TX); configure_out_port(p_midi_out, clk_midi, 1<<MIDI_SHIFT_TX);
configure_in_port(p_midi_in, clk_midi); configure_in_port(p_midi_in, clk_midi);
@@ -167,14 +169,16 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
unsigned event = 0; unsigned event = 0;
uin_count++; uin_count++;
rxByte >>= 24; rxByte >>= 24;
// if (rxByte != outputted_symbol) { #if 0
// // Loopback check // Loopback check
// printhexln(rxByte); if ((rxByte != outputted_symbol))
// printhexln(outputted_symbol); {
// } printhexln(rxByte);
printhexln(outputted_symbol);
}
#endif
{valid, event} = midi_in_parse(mips, cable_number, rxByte); {valid, event} = midi_in_parse(mips, cable_number, rxByte);
if (valid && isempty(midi_to_host_fifo)) if (valid && queue_is_empty(midi_to_host_fifo))
{ {
event = byterev(event); event = byterev(event);
@@ -189,7 +193,7 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
} }
else else
{ {
enqueue(midi_to_host_fifo, event); queue_push_word(midi_to_host_fifo, midi_to_host_fifo_arr, event);
} }
} }
else if (valid) else if (valid)
@@ -215,10 +219,10 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
// When it has just finished sending a symbol // When it has just finished sending a symbol
// Take from FIFO // Take from FIFO
outputting_symbol = dequeue(symbol_fifo); outputting_symbol = queue_pop_word(symbol_fifo, symbol_fifo_arr);
symbol = makeSymbol(outputting_symbol); symbol = makeSymbol(outputting_symbol);
if (space(symbol_fifo) > 3 && midi_from_host_overflow) if (queue_space(symbol_fifo) > 3 && midi_from_host_overflow)
{ {
midi_from_host_overflow = 0; midi_from_host_overflow = 0;
midi_send_ack(c_midi); midi_send_ack(c_midi);
@@ -244,7 +248,7 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
// Finished sending byte // Finished sending byte
uout_count++; uout_count++;
outputted_symbol = outputting_symbol; outputted_symbol = outputting_symbol;
if (isempty(symbol_fifo)) if (queue_is_empty(symbol_fifo))
{ // FIFO empty { // FIFO empty
isTX = 0; isTX = 0;
} }
@@ -259,10 +263,10 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
{ {
// have we got more data to send // have we got more data to send
//printstr("ack\n"); //printstr("ack\n");
if (!isempty(midi_to_host_fifo)) if (!queue_is_empty(midi_to_host_fifo))
{ {
//printstr("uart->decouple\n"); //printstr("uart->decouple\n");
outuint(c_midi, dequeue(midi_to_host_fifo)); outuint(c_midi, queue_pop_word(midi_to_host_fifo, midi_to_host_fifo_arr));
th_count++; th_count++;
} }
else else
@@ -278,7 +282,7 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
int event = byterev(datum); int event = byterev(datum);
mr_count++; mr_count++;
#ifdef MIDI_LOOPBACK #ifdef MIDI_LOOPBACK
if (isempty(midi_to_host_fifo)) if (queue_is_empty(midi_to_host_fifo))
{ {
// data to send to host // data to send to host
if (!waiting_for_ack) if (!waiting_for_ack)
@@ -292,7 +296,7 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
else else
{ {
event = byterev(event); event = byterev(event);
enqueue(midi_to_host_fifo, event); queue_push_word(midi_to_host_fifo, midi_to_host_fifo_arr, event);
} }
midi_send_ack(c_midi); midi_send_ack(c_midi);
} }
@@ -305,10 +309,10 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
for (int i = 0; i != size; i++) for (int i = 0; i != size; i++)
{ {
// add symbol to fifo // add symbol to fifo
enqueue(symbol_fifo, midi[i]); queue_push_word(symbol_fifo, symbol_fifo_arr, midi[i]);
} }
if (space(symbol_fifo) > 3) if (queue_space(symbol_fifo) > 3)
{ {
midi_send_ack(c_midi); midi_send_ack(c_midi);
} }
@@ -331,11 +335,11 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
/* Check for special case where MIDI ports are shared with i2c ports */ /* Check for special case where MIDI ports are shared with i2c ports */
if(isnull(c_i2c) && isnull(p_scl) && isnull(p_sda)) if(isnull(c_i2c) && isnull(p_scl) && isnull(p_sda))
{ {
handle_iap_case(is_ack, is_reset, datum, c_iap, c_i2c, p_midi_out, p_midi_in); iap_handle_ack_or_reset_or_data(is_ack, is_reset, datum, c_iap, c_i2c, p_midi_out, p_midi_in);
} }
else else
{ {
handle_iap_case(is_ack, is_reset, datum, c_iap, c_i2c, p_scl, p_sda); iap_handle_ack_or_reset_or_data(is_ack, is_reset, datum, c_iap, c_i2c, p_scl, p_sda);
} }
if (!authenticating) if (!authenticating)
{ {
@@ -347,7 +351,7 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
/* Slow timer looking for IDevice plug/unplug event */ /* Slow timer looking for IDevice plug/unplug event */
case iAPTimer when timerafter(polltime) :> void: case iAPTimer when timerafter(polltime) :> void:
printintln(polltime); printintln(polltime);
handle_poll_dev_det(iAPTimer); iap_handle_poll_dev_det(iAPTimer);
break; break;
#endif #endif
} }

View File

@@ -0,0 +1,32 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET = XP-SKC-SU1
# The APP_NAME variable determines the name of the final .xe file. It should
# not include the .xe postfix. If left blank the name will default to
# the project name
APP_NAME = app_queue_test
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = module_queue
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = -O0 -g
# The VERBOSE variable, if set to 1, enables verbose output from the make system.
VERBOSE = 0
# This change to the module path is so that this application can be in the
# tests sub-directory in it's git repo
ifeq ($(notdir $(abspath ..)),tests)
PATHSEP = $(if $(findstring Windows, $(OS))$(findstring WINDOWS,$(OS)),;,:)
XMOS_MODULE_PATH := $(XMOS_MODULE_PATH)$(PATHSEP)../../..
endif
XMOS_MAKE_PATH ?= ../..
-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,32 @@
#include "queue.h"
#include <stdlib.h>
#define VERIFY(x) do { if (!(x)) _Exit(1); } while(0)
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
int main()
{
queue_t q;
unsigned array[4];
const unsigned size = ARRAY_SIZE(array);
queue_init(q, size);
VERIFY(queue_is_empty(q));
VERIFY(!queue_is_full(q));
VERIFY(queue_items(q) == 0);
VERIFY(queue_space(q) == size);
queue_push_word(q, array, 1);
VERIFY(!queue_is_empty(q));
VERIFY(queue_items(q) == 1);
VERIFY(queue_space(q) == size - 1);
for (unsigned i = 1; i < size; i++) {
queue_push_word(q, array, i + 1);
}
VERIFY(queue_is_full(q));
VERIFY(queue_items(q) == size);
VERIFY(queue_space(q) == 0);
for (unsigned i = 0; i < size; i++) {
VERIFY(queue_pop_word(q, array) == i + 1);
}
return 0;
}

19
xpd.xml
View File

@@ -1,9 +1,26 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<xpd> <xpd>
<components>
<component description = "module_dfu" type = "demoCode" scope = "General Use" path = "module_dfu" local = "false" id = "module_dfu" name = "module_dfu">
<board>XMOS USB Audio Reference Designes</board>
<keyword>DFU</keyword>
</component>
</components>
<dependency repo = "sc_util">
<githash>d0531d7c68ab67334582c324828e36d617baf8b3</githash>
<uri>git://github.com/xcore/sc_util</uri>
<version>1.0.3rc0</version>
</dependency>
<description>USB Audio Shared Components. For use in the XMOS USB Audio Refererence Designs.</description> <description>USB Audio Shared Components. For use in the XMOS USB Audio Refererence Designs.</description>
<git_export>False</git_export>
<location>git://git/apps/sc_usb_audio</location> <location>git://git/apps/sc_usb_audio</location>
<name>USB Audio Shared Components</name> <name>USB Audio Shared Components</name>
<maintainer>xross</maintainer>
<vendor>XMOS</vendor> <vendor>XMOS</vendor>
<version_defines>
<version_define name = "BCD_DEVICE_J" format = "%MAJOR%"></version_define>
<version_define name = "BCD_DEVICE_M" format = "%MINOR%"></version_define>
<version_define name = "BDC_DEVICE_N" format = "%POINT%"></version_define>
</version_defines>
<xpd_version>1.0</xpd_version> <xpd_version>1.0</xpd_version>
<git_export>False</git_export>
</xpd> </xpd>