From cce3743ba373071b4a280dfcf1800a7a8538c85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Mon, 21 Oct 2019 11:31:48 +0200 Subject: [PATCH 1/9] Add libfx2 as submodule beside fx2lib --- .gitmodules | 3 +++ third_party/libfx2 | 1 + 2 files changed, 4 insertions(+) create mode 160000 third_party/libfx2 diff --git a/.gitmodules b/.gitmodules index e378912..5d5a486 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "third_party/fx2lib-linux-headers"] path = third_party/fx2lib-linux-headers url = https://github.com/mithro/fx2lib-linux-headers +[submodule "third_party/libfx2"] + path = third_party/libfx2 + url = git@dev.antmicro.com:fpga-ecosystem-libfx2.git diff --git a/third_party/libfx2 b/third_party/libfx2 new file mode 160000 index 0000000..3adb4fc --- /dev/null +++ b/third_party/libfx2 @@ -0,0 +1 @@ +Subproject commit 3adb4fc842f174b0686ed122c0309d68356edc11 From 371d715a4590b63ea06a4c1a58ae3d121d43d25f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Fri, 25 Oct 2019 10:30:29 +0200 Subject: [PATCH 2/9] Change libfx2 submodule url to original whitequark/libfx2 on github --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 5d5a486..5d22636 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,4 +6,4 @@ url = https://github.com/mithro/fx2lib-linux-headers [submodule "third_party/libfx2"] path = third_party/libfx2 - url = git@dev.antmicro.com:fpga-ecosystem-libfx2.git + url = https://github.com/whitequark/libfx2.git From 01399f92f324a5f24c844bc14b91be5bd12018d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Fri, 29 Nov 2019 15:08:41 +0100 Subject: [PATCH 3/9] remove uneeded submodules --- third_party/fx2lib | 1 - third_party/fx2lib-linux-headers | 1 - 2 files changed, 2 deletions(-) delete mode 160000 third_party/fx2lib delete mode 160000 third_party/fx2lib-linux-headers diff --git a/third_party/fx2lib b/third_party/fx2lib deleted file mode 160000 index a5b0c2e..0000000 --- a/third_party/fx2lib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a5b0c2e54482d5e9f1806b7790e43f7fb95e6653 diff --git a/third_party/fx2lib-linux-headers b/third_party/fx2lib-linux-headers deleted file mode 160000 index 01688ae..0000000 --- a/third_party/fx2lib-linux-headers +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 01688aee0390146008b8592515e8bfa13cb9f046 From bc012bb9fe9f8787db18460dd56f233284c93430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Fri, 29 Nov 2019 15:09:23 +0100 Subject: [PATCH 4/9] remove old fx2lib examples --- examples/common.mk | 90 ------------------------ examples/lights/Makefile | 30 -------- examples/lights/README.md | 11 --- examples/lights/TODO | 1 - examples/lights/lights.c | 77 -------------------- examples/serial/Makefile | 31 -------- examples/serial/README.md | 32 --------- examples/serial/docs/serial_diagram.png | Bin 11295 -> 0 bytes examples/serial/serial.c | 74 ------------------- 9 files changed, 346 deletions(-) delete mode 100644 examples/common.mk delete mode 100644 examples/lights/Makefile delete mode 100644 examples/lights/README.md delete mode 100644 examples/lights/TODO delete mode 100644 examples/lights/lights.c delete mode 100644 examples/serial/Makefile delete mode 100644 examples/serial/README.md delete mode 100644 examples/serial/docs/serial_diagram.png delete mode 100644 examples/serial/serial.c diff --git a/examples/common.mk b/examples/common.mk deleted file mode 100644 index ce7a082..0000000 --- a/examples/common.mk +++ /dev/null @@ -1,90 +0,0 @@ -# -# Copyright (C) 2009-2012 Chris McClelland -# Copyright (C) 2015 Joel Stanley -# Copyright (C) 2017 Kyle Robbertze -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see . -# - -# To build the firmware you will need: -# SDCC from http://sdcc.sourceforge.net -# Git from https://git-scm.com/ -# -# To load the firmware you will need: -# HDMI2USB-mode-swtich from https://github.com/timvideos/HDMI2USB-mode-switch -# -LIBS ?= $(FX2LIBDIR)/lib/fx2.lib -INCS += -I sdcc -I$(FX2LIBDIR)/include -I. -I../../common/boards - -USE_16K ?= 1 - -CC_OBJS ?= $(CC_SRCS:%.c=%.rel) - -CC = sdcc - -CFLAGS += -mmcs51 --xram-size 0x0200 $(FLAGS) -CFLAGS += -DBOARD_$(BOARD) - -ifeq ($(USE_16K),1) - CFLAGS += --code-size 0x3e00 -else - CFLAGS += --code-size 0x1e00 -endif - -# Use make V=1 for a verbose build. -ifndef V - Q_CC=@echo ' CC ' $@; - Q_AS=@echo ' AS ' $@; - Q_LINK=@echo ' LINK ' $@; - Q_RM=@echo ' CLEAN '; - Q_OBJCOPY=@echo ' OBJCOPY ' $@; - Q_GEN=@echo ' GEN ' $@; -endif - -.PHONY: all clean - -all: $(TARGET).hex - -$(CC_SRCS): $(FX2LIBDIR)/lib/fx2.lib - -$(FX2LIBDIR)/lib/fx2.lib: $(FX2LIBDIR)/.git - cd $(dir $@) && make -j1 - - -# We depend on a file inside the directory as git creates an -# empty dir for us. -# -# Note that although we have the variable FX2LIBDIR, the submodule -# magic will always check it out in fx2lib/ -$(FX2LIBDIR)/.git: $(GITMODULESDIR) - git submodule sync --recursive -- $$(dirname $@) - git submodule update --recursive --init $$(dirname $@) - touch $@ -r $< - -$(TARGET).hex: $(CC_OBJS) - $(Q_LINK)$(CC) $(CFLAGS) -o $@ $+ $(LIBS) - -%.rel: %.c - $(Q_CC)$(CC) $(CFLAGS) -c --disable-warning 85 $(INCS) $? - -clean: - $(Q_RM)$(RM) *.iic *.asm *.lnk *.lst *.map *.mem *.rel *.rst *.sym \ - *.lk serial.hex - cd $(FX2LIBDIR) && make clean - -distclean: clean - $(RM) -r $(FX2LIBDIR) - -load: $(TARGET).hex - hdmi2usb-mode-switch --load-fx2-firmware $(TARGET).hex diff --git a/examples/lights/Makefile b/examples/lights/Makefile deleted file mode 100644 index eb1a06a..0000000 --- a/examples/lights/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (C) 2009-2012 Chris McClelland -# Copyright (C) 2015 Joel Stanley -# Copyright (C) 2017 Kyle Robbertze -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see . -# -# To build the firmware you will need: -# SDCC from http://sdcc.sourceforge.net -# fx2lib from http://fx2lib.wiki.sourceforge.net -# -TARGET := lights -FX2LIBDIR := ../../third_party/fx2lib -GITMODULESDIR := ../../.gitmodules -BOARD ?= fx2miniboard - -CC_SRCS := lights.c - -include ../common.mk diff --git a/examples/lights/README.md b/examples/lights/README.md deleted file mode 100644 index e157a73..0000000 --- a/examples/lights/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Lights Example -This example flashes the LEDs present on the FX2LP CY7C68013A mini board. It -can be used for testing loading of firmware onto these boards. The expected -pattern is D1 turning on, then D2 250ms later, then D1 off, then D2 off and the -cycle repeats - -The firmware is built using `make` and loaded using `make load`, which uses the -[HDMI2USB-mode-switch](https://github.com/timvideos/HDMI2USB-mode-switch) -utility to load the firmware onto the FX2 chip. - -![](../../docs/lights_example.gif) diff --git a/examples/lights/TODO b/examples/lights/TODO deleted file mode 100644 index f1c8035..0000000 --- a/examples/lights/TODO +++ /dev/null @@ -1 +0,0 @@ -Make this compatible with the Atlys and Opsis boards diff --git a/examples/lights/lights.c b/examples/lights/lights.c deleted file mode 100644 index c69f3da..0000000 --- a/examples/lights/lights.c +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (C) 2009 Ubixum, Inc. -// Copyright (C) 2016 Matthew Iselin -// Copyright (C) 2017 Kyle Robbertze -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** \file lights.c - * Example firmware that flashes LEDs. - * - * On the Atlys this is LD14 (DONE), on the FX2 miniboard D1 and D2 and on the - * Opsis it is D2 - */ - -#include -#include -#include - -#include "fx2lights.h" - -void init_lights(void) { - // Set pins to port mode instead of GPIF master/slave mode - IFCONFIG &= ~(bmIFCFGMASK); - // No alternate functions -#ifdef BOARD_fx2miniboard - PORTACFG = 0x00; -#endif // BOARD_fx2miniboard -#ifdef BOARD_opsis - PORTECFG = 0x00; -#endif // BOARD_opsis -} - -void main(void) { - BYTE n=0; - - init_lights(); - - while(TRUE) { - switch(n) { - case 0: - /** - * d1 is the LED labelled LD14 on the Atlys and the LED labelled - * D1 on the FX2LP CY7C68013A mini-board. It is not connected on - * the Opsis - */ - d1on(); - break; - case 1: - /** - * d2 is the LED labelled D2 on the Numato Opsis and the LED - * labelled D2 on the FX2LP CY7C68013A mini-board. It is not - * connected on the Atlys - */ - d2on(); - break; - case 2: - d1off(); - break; - default: - d2off(); - break; - } - delay(250); - n = (n + 1) % 4; - } -} diff --git a/examples/serial/Makefile b/examples/serial/Makefile deleted file mode 100644 index 11fc546..0000000 --- a/examples/serial/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (C) 2009-2012 Chris McClelland -# Copyright (C) 2015 Joel Stanley -# Copyright (C) 2017 Kyle Robbertze -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see . -# - -# To build the firmware you will need: -# SDCC from http://sdcc.sourceforge.net -# fx2lib from http://fx2lib.wiki.sourceforge.net -# -TARGET := serial -FX2LIBDIR := ../../third_party/fx2lib -GITMODULESDIR := ../../.gitmodules -BOARD ?= fx2miniboard - -CC_SRCS := serial.c - -include ../common.mk diff --git a/examples/serial/README.md b/examples/serial/README.md deleted file mode 100644 index 8456a2b..0000000 --- a/examples/serial/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Serial Example - -This serial example is for testing serial connections from the FX2 chip. It is -uses the same setup as the HDMI2USB firmware, which is: - - * Baud rate of 115200 - * Serial device /dev/ttyUSB0 (default on linux) - * Connections - - RXD -> PD3 - - GND -> GND - -This example prints "This is the serial example for the HDMI2USB firmware" to -the TXD pin every two seconds - -To build the firmware run `make`, which will pull in the required dependencies -and build the `serial.hex` firmware image. This can be loaded using the -[HDMI2USB-mode-switch](https://github.com/timvideos/HDMI2USB-mode-switch) -utility, which is what `make load` uses. - -Under linux serial can be read using minicom. This example was tested using the -Digilent PmodUSBUART Serial to USB adaptor. - -FIXME: Add minicom example. - -FIXME: Only the Atlys and FX2 Dev board uses bit banging, the Opsis uses the -hardware serial. - -## Wiring Diagram - -FIXME: Use real pictures in the diagram. - -![](docs/serial_diagram.png) diff --git a/examples/serial/docs/serial_diagram.png b/examples/serial/docs/serial_diagram.png deleted file mode 100644 index f82d14efedcf2f30393ab27834c507710b491be8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11295 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 diff --git a/examples/serial/serial.c b/examples/serial/serial.c deleted file mode 100644 index b9d1a52..0000000 --- a/examples/serial/serial.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2017 Kyle Robbertze - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -#include -#include -#include -#include - -#define PD3 0xB3 -#define BAUD 32 // FIXME: Figure out why this is 32 - -__sbit __at PD3 USART; // USART slave send from port D3 - -void usart_init(void) { - SETCPUFREQ(CLK_48M); - USART = 1; - OED |= 0xff; // Set all pins' outputs enabled -} - -void usart_send_byte(BYTE c) { - (void)c; /* argument passed in DPL */ - __asm - mov a, dpl - mov r1, #9 // Move 9 into r1 for loop to execute 8 times (byte) - clr c - loop: - mov _USART, c // Move c into USART register - rrc a // Rotate accumulator 1 bit right - mov r0, #BAUD // Indicate ready to send - djnz r0, . // Wait for r0 to be cleared - nop - djnz r1, loop // Reduce r1 and start loop again - - setb _USART // Stop bit - mov r0, #BAUD // Indicate ready to send - djnz r0, . // Wait to be sent - __endasm; -} - -void usart_send_string(const char *s) { - while (*s) { - switch (*s) { - case '\r': // Send new line and carriage return so there is less - case '\n': // configuration of serial software needed. - usart_send_byte('\n'); - usart_send_byte('\r'); - break; - default: - usart_send_byte(*s); - } - *s++; - } -} - -void main(void) { - usart_init(); - while (1) { - usart_send_string("This is the serial example for the HDMI2USB firmware\n"); - delay(2000); - } -} From 3b409b092c3921a8e3dc28e51a76df2f24214e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Mon, 9 Dec 2019 11:23:28 +0100 Subject: [PATCH 5/9] add usb audio device example --- common/common.mk | 140 ++++------------ common/uac.c | 175 ++++++++++++++++++++ common/uac.h | 48 ++++++ common/uac_defs.h | 311 +++++++++++++++++++++++++++++++++++ common/usb_defs.h | 36 ++++ examples/audio/Makefile | 7 + examples/audio/descriptors.c | 56 +++++++ examples/audio/main.c | 52 ++++++ examples/common/uac.d | 7 + 9 files changed, 725 insertions(+), 107 deletions(-) create mode 100644 common/uac.c create mode 100644 common/uac.h create mode 100644 common/uac_defs.h create mode 100644 common/usb_defs.h create mode 100644 examples/audio/Makefile create mode 100644 examples/audio/descriptors.c create mode 100644 examples/audio/main.c create mode 100644 examples/common/uac.d diff --git a/common/common.mk b/common/common.mk index 4344bb9..8038713 100644 --- a/common/common.mk +++ b/common/common.mk @@ -1,114 +1,40 @@ -# -# Copyright (C) 2009-2012 Chris McClelland -# Copyright 2015 Joel Stanley -# Copyright 2017 Kyle Robbertze -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see . -# +# configuration +BOARD ?= opsis +MODEL ?= small +SYNCDELAYLEN ?= 4 -# To build the firmware you will need: -# SDCC from http://sdcc.sourceforge.net -# Git from https://git-scm.com/ -# -# To build a firmware suitable for loading into RAM: -# make -# -# To build a firmware suitable for loading from EEPROM: -# make FLAGS="-DEEPROM" -# -# To load a firmware: -# make load -# You will need HDMI2USB-mode-switch from -# https://github.com/timvideos/HDMI2USB-mode-switch -# -# Common rules +# use conda enviorment if it exists MAKEFILE_PATH := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) export PATH := $(MAKEFILE_PATH)../conda/bin:$(PATH) -LIBS ?= $(FX2LIBDIR)/lib/fx2.lib -INCS += -I sdcc -I$(FX2LIBDIR)/include -I. -I$(COMMON_DIR)/boards - -# Settings specific for the TimVideo hdmi2usb firmware -BOARD ?= opsis -FLAGS +=-DDEBUG -DBOARD_$(BOARD) - -# Must only be hex numbers -FIRMWARE_VERSION := $(shell date +%Y%m%d) - -CC_OBJS := $(CC_SRCS:%.c=%.rel) -AS_OBJS := $(AS_SRCS:%.a51=%.rel) - -CC := sdcc -AS8051 := sdas8051 -AS := $(AS8051) - -CFLAGS += -DDATE=0x$(FIRMWARE_VERSION) -mmcs51 $(FLAGS) -CFLAGS += --std-c99 -DSDCC -Wa"-p" --xram-size 0x0200 - -# Use make V=1 for a verbose build. -ifndef V - Q_CC=@echo ' CC ' $@; - Q_AS=@echo ' AS ' $@; - Q_LINK=@echo ' LINK ' $@; - Q_RM=@echo ' CLEAN '; - Q_OBJCOPY=@echo ' OBJCOPY ' $@; - Q_GEN=@echo ' GEN ' $@; +CFLAGS = +CFLAGS += --std-sdcc99 +CFLAGS += -Wa"-p" +CFLAGS += --xram-size 0x0200 +CFLAGS += -DSYNCDELAYLEN=$(SYNCDELAYLEN) + +# should to override previously set flags +FLAGS ?= +CFLAGS += $(FLAGS) + +# set USB IDs depending on board +ifeq (${BOARD},atlys) + VID := 1D50 + PID := 60B7 + DID := 0002 +else + ifeq (${BOARD},opsis) + VID := 2A19 + PID := 5442 + DID := 0002 + else + $(error "Unknown board type '$(BOARD)'") + endif endif -.PHONY: all clean distclean check check-descriptors check_int2jt load - -all: $(TARGET).hex - -check_int2jt: $(TARGET).hex - @export REQUESTED=$(shell grep "INT2JT=" $(TARGET).map | sed -e's/INT2JT=//'); \ - export ACTUAL=$(shell grep "C:.*INT2JT" $(TARGET).map | sed -e's/C: *0*\([^ ]*\) _INT2JT.*/0x\1/' | tr A-Z a-z ); \ - if [ "$$REQUESTED" != "$$ACTUAL" ]; then \ - echo "INT2JT at $$ACTUAL but requested $$REQUESTED"; \ - exit 1; \ - fi - -check: check_int2jt - -clean: - $(Q_RM)$(RM) *.adb *.asm *.cdb *.iic *.lk *.lnk *.lst *.omf *.map \ - *.mem *.rel *.rst *.sym descriptors_strings.* a.out date.h \ - date.inc progOffsets.h version_data.h version_data.c ${TARGET}.hex - cd $(FX2LIBDIR) && make clean - -distclean: clean - $(RM) -r $(FX2LIBDIR) - -load: $(TARGET).hex - hdmi2usb-mode-switch --load-fx2-firmware $(TARGET).hex - -$(CC_SRCS) $(AS_SRCS): $(FX2LIBDIR)/lib/fx2.lib - -$(FX2LIBDIR)/lib/fx2.lib: $(FX2LIBDIR)/.git - cd $(dir $@) && make -j1 - -# We depend on a file inside the directory as git creates an -# empty dir for us. -# -# Note that although we have the variable FX2LIBDIR, the submodule -# magic will always check it out in fx2lib/ -$(FX2LIBDIR)/.git: ../.gitmodules - git submodule sync --recursive -- $$(dirname $@) - git submodule update --recursive --init $$(dirname $@) - touch $@ -r ../.gitmodules - -$(TARGET).hex: $(CC_OBJS) $(AS_OBJS) - $(Q_LINK)$(CC) $(CFLAGS) -o $@ $+ $(LIBS) +CFLAGS += -DVID=0x$(VID) -DPID=0x$(PID) -DDID=0x$(DID) -%.rel: %.a51 - $(Q_AS)$(AS) -logs $? +LIBFX2DIR ?= ../third_party/libfx2 +# variable required by libfx2 build system +LIBFX2 = $(LIBFX2DIR)/firmware/library +include $(LIBFX2)/fx2rules.mk diff --git a/common/uac.c b/common/uac.c new file mode 100644 index 0000000..733c0ab --- /dev/null +++ b/common/uac.c @@ -0,0 +1,175 @@ +#include "uac.h" + +extern usb_descriptor_set_c usb_descriptor_set; + +// keeps track of current alternate setting of streaming interface +__xdata uint8_t uac_as_alt_setting = 0; +// store the interface numbers for set/get interface handlers +__xdata static uint8_t if_num_ctrl; +__xdata static uint8_t if_num_streaming; + +bool uac_handle_usb_set_interface(uint8_t interface, uint8_t alt_setting) { + if (interface == if_num_ctrl && alt_setting == 0) { + usb_reset_data_toggles(&usb_descriptor_set, interface, alt_setting); + return true; + } + if (interface == if_num_streaming && (alt_setting == 0 || alt_setting == 1)) { + // I belive we do not need to reset our endpoint configuration regsiters, as host should know + // that in alt_setting 0 there are no endpoints associated with this interface, so host will + // not send any IN requests + uac_as_alt_setting = alt_setting; + usb_reset_data_toggles(&usb_descriptor_set, interface, alt_setting); + return true; + } + return false; // not handled +} + +bool uac_handle_usb_get_interface(uint8_t interface) { + if (interface == if_num_ctrl) { + EP0BUF[0] = 0; // only 1 alternate setting + SETUP_EP0_BUF(1); + } + if (interface == if_num_ctrl) { + EP0BUF[0] = uac_as_alt_setting; + SETUP_EP0_BUF(1); + } + return false; // not handled +} + +void uac_config(struct uac_configuration *config) { + if_num_ctrl = config->if_num_ctrl; + if_num_streaming = config->if_num_ctrl + 1; + // interface numbers + ((__xdata struct usb_desc_interface *) &usb_uac_std_ac_interface)->bInterfaceNumber = if_num_ctrl; + ((__xdata struct usb_desc_interface *) &usb_uac_std_streaming_interface_alt0)->bInterfaceNumber = if_num_streaming; + ((__xdata struct usb_desc_interface *) &usb_uac_std_streaming_interface_alt1)->bInterfaceNumber = if_num_streaming; + ((__xdata struct usb_desc_uac1_ac_header *) &usb_uac_ac_header)->baInterfaceNr[0] = if_num_streaming; + // endpoint numbers + ((__xdata struct usb_desc_endpoint *) &usb_uac_audio_endpoint)->bEndpointAddress = config->ep_addr_streaming | USB_DIR_IN; + // strings + ((__xdata struct usb_desc_uac_input_terminal *) &usb_uac_input_terminal)->iChannelNames = config->i_str_channel_left; +} + +/*** Descriptors **************************************************************/ + +usb_desc_interface_c usb_uac_std_ac_interface = { + .bLength = sizeof(struct usb_desc_interface), + .bDescriptorType = USB_DESC_INTERFACE, + .bInterfaceNumber = 0, // uac_config + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, + .bInterfaceProtocol = 0, + .iInterface = 0, +}; + +#define LENGTH_uac_input_terminal (sizeof(struct usb_desc_uac_input_terminal)) +usb_desc_uac_input_terminal_c usb_uac_input_terminal = { + .bLength = LENGTH_uac_input_terminal, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubtype = UAC_INPUT_TERMINAL, + .bTerminalID = 1, + .wTerminalType = UAC_INPUT_TERMINAL_MICROPHONE, + .bAssocTerminal = 0, + .bNrChannels = 2, // stereo + .wChannelConfig = (UAC_CHANNEL_LEFT | UAC_CHANNEL_RIGHT), + .iChannelNames = 0, // uvc_config // first channel name, other channels must have consequetive indices + .iTerminal = 0, +}; + +#define LENGTH_uac_output_terminal (sizeof(struct usb_desc_uac1_output_terminal)) +usb_desc_uac1_output_terminal_c usb_uac_output_terminal = { + .bLength = LENGTH_uac_output_terminal, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, + .bTerminalID = 2, + .wTerminalType = UAC_OUTPUT_TERMINAL_STREAMING, + .bAssocTerminal = 0, + .bSourceID = 1, // connected to input terminal + .iTerminal = 0, +}; + +#define LENGTH_uac_ac_header (sizeof(struct usb_desc_uac1_ac_header) + 1) +usb_desc_uac1_ac_header_c usb_uac_ac_header = { + .bLength = LENGTH_uac_ac_header, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubtype = UAC_MS_HEADER, + .bcdADC = UAC_BCD_V10, + .wTotalLength = // this descriptor + all unit and terminal descriptors + LENGTH_uac_ac_header + + LENGTH_uac_input_terminal + + LENGTH_uac_output_terminal, + .bInCollection = 1, // one interface in collection + .baInterfaceNr = { 0 }, // uac_config // streaing interface +}; + +// Setting 0 of streaming interface, no endpoints which means this is a zero-bandwidth +// setting to allow host to temporarily disable audio in case of bandiwdth problems +usb_desc_interface_c usb_uac_std_streaming_interface_alt0 = { + .bLength = sizeof(struct usb_desc_interface), + .bDescriptorType = USB_DESC_INTERFACE, + .bInterfaceNumber = 0, // uac_config + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = 0, + .iInterface = 0, +}; + +// Setting 1 of streaming interface, regular operation +usb_desc_interface_c usb_uac_std_streaming_interface_alt1 = { + .bLength = sizeof(struct usb_desc_interface), + .bDescriptorType = USB_DESC_INTERFACE, + .bInterfaceNumber = 0, // uac_config + .bAlternateSetting = 1, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = 0, + .iInterface = 0, +}; + +usb_desc_uac1_as_header_c usb_uac_as_header = { + .bLength = sizeof(struct usb_desc_uac1_as_header), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubtype = UAC_AS_GENERAL, + .bTerminalLink = 2, // connected to output terminal + .bDelay = 1, + .wFormatTag = UAC_FORMAT_TYPE_I_PCM, +}; + +usb_desc_uac_format_type_i_discrete_c usb_uac_format = { + .bLength = sizeof(struct usb_desc_uac_format_type_i_discrete) + 3, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubtype = UAC_FORMAT_TYPE, + .bFormatType = UAC_FORMAT_TYPE_I, + .bNrChannels = 2, + .bSubframeSize = 2, + .bBitResolution = 16, + .bSamFreqType = 1, + .tSamFreq = {{0x40, 0x1F, 0x00}}, // 8000Hz, little endian +}; + +/*** UAC: endpoints ***********************************************************/ + +usb_desc_audio_endpoint_c usb_uac_audio_endpoint = { + .bLength = sizeof(struct usb_desc_audio_endpoint), + .bDescriptorType = USB_DESC_ENDPOINT, + .bEndpointAddress = 0, // uac_config + .bmAttributes = USB_XFER_ISOCHRONOUS, + .wMaxPacketSize = 512, + .bInterval = 4, + .bRefresh = 0, + .bSynchAddress = 0, +}; + +usb_desc_uac_iso_endpoint_c usb_uac_iso_endpoint = { + .bLength = sizeof(struct usb_desc_uac_iso_endpoint), + .bDescriptorType = USB_DT_CS_ENDPOINT, + .bDescriptorSubtype = UAC_AS_GENERAL, + .bmAttributes = 0, + .bLockDelayUnits = 0, + .wLockDelay = 0, +}; diff --git a/common/uac.h b/common/uac.h new file mode 100644 index 0000000..59b9405 --- /dev/null +++ b/common/uac.h @@ -0,0 +1,48 @@ +#ifndef UAC_H +#define UAC_H + +#include +#include "uac_defs.h" + +// control and streaming interface +#define UAC_NUM_INTERFACES 2 + +// UAC descriptors +extern usb_desc_interface_c usb_uac_std_ac_interface; +extern usb_desc_uac_input_terminal_c usb_uac_input_terminal; +extern usb_desc_uac1_output_terminal_c usb_uac_output_terminal; +extern usb_desc_uac1_ac_header_c usb_uac_ac_header; +extern usb_desc_interface_c usb_uac_std_streaming_interface_alt0; +extern usb_desc_interface_c usb_uac_std_streaming_interface_alt1; +extern usb_desc_uac1_as_header_c usb_uac_as_header; +extern usb_desc_uac_format_type_i_discrete_c usb_uac_format; +extern usb_desc_audio_endpoint_c usb_uac_audio_endpoint; +extern usb_desc_uac_iso_endpoint_c usb_uac_iso_endpoint; + +// TODO: { .generic = (struct usb_desc_generic *) &usb_uac_if_assoc }, +// Marco for adding descriptors to usb_configuration_c +#define UAC_DESCRIPTORS_LIST \ + { .interface = &usb_uac_std_ac_interface }, \ + { .generic = (struct usb_desc_generic *) &usb_uac_ac_header }, \ + { .generic = (struct usb_desc_generic *) &usb_uac_input_terminal }, \ + { .generic = (struct usb_desc_generic *) &usb_uac_output_terminal }, \ + { .interface = &usb_uac_std_streaming_interface_alt0 }, \ + { .interface = &usb_uac_std_streaming_interface_alt1 }, \ + { .generic = (struct usb_desc_generic *) &usb_uac_as_header }, \ + { .generic = (struct usb_desc_generic *) &usb_uac_format }, \ + { .generic = (struct usb_desc_generic *) &usb_uac_audio_endpoint }, \ + { .generic = (struct usb_desc_generic *) &usb_uac_iso_endpoint }, + +struct uac_configuration { + uint8_t if_num_ctrl; + // if_num_streaming = if_num_ctrl + 1 + uint8_t ep_addr_streaming; + uint8_t i_str_channel_left; // index of left channel string + // i_str_channel_right = i_str_channel_left + 1 +}; + +void uac_config(struct uac_configuration *config); +bool uac_handle_usb_set_interface(uint8_t interface, uint8_t alt_setting); +bool uac_handle_usb_get_interface(uint8_t interface); + +#endif /* UAC_H */ diff --git a/common/uac_defs.h b/common/uac_defs.h new file mode 100644 index 0000000..ac34996 --- /dev/null +++ b/common/uac_defs.h @@ -0,0 +1,311 @@ +#ifndef UAC_DEFS_H +#define UAC_DEFS_H + +/* USB Audio Class */ + +#include "usb_defs.h" + +// TODO: this has been extracted from linux headers, but should be organised better, +// we also need one naming convention corresponding to that in libfx2 +enum { + /* bInterfaceProtocol values to denote the version of the standard used */ + UAC_VERSION_1 = 0x00, + UAC_VERSION_2 = 0x20, + + USB_CLASS_AUDIO = 0x01, + + /* A.2 Audio Interface Subclass Codes */ + USB_SUBCLASS_AUDIOCONTROL = 0x01, + USB_SUBCLASS_AUDIOSTREAMING = 0x02, + USB_SUBCLASS_MIDISTREAMING = 0x03, + + /* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */ + UAC_HEADER = 0x01, + UAC_INPUT_TERMINAL = 0x02, + UAC_OUTPUT_TERMINAL = 0x03, + UAC_MIXER_UNIT = 0x04, + UAC_SELECTOR_UNIT = 0x05, + UAC_FEATURE_UNIT = 0x06, + UAC1_PROCESSING_UNIT = 0x07, + UAC1_EXTENSION_UNIT = 0x08, + + /* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */ + UAC_AS_GENERAL = 0x01, + UAC_FORMAT_TYPE = 0x02, + UAC_FORMAT_SPECIFIC = 0x03, + + /* A.7 Processing Unit Process Types */ + UAC_PROCESS_UNDEFINED = 0x00, + UAC_PROCESS_UP_DOWNMIX = 0x01, + UAC_PROCESS_DOLBY_PROLOGIC = 0x02, + UAC_PROCESS_STEREO_EXTENDER = 0x03, + UAC_PROCESS_REVERB = 0x04, + UAC_PROCESS_CHORUS = 0x05, + UAC_PROCESS_DYN_RANGE_COMP = 0x06, + + /* A.8 Audio Class-Specific Endpoint Descriptor Subtypes */ + UAC_EP_GENERAL = 0x01, + + /* A.9 Audio Class-Specific Request Codes */ + UAC_SET_ = 0x00, + UAC_GET_ = 0x80, + + UAC__CUR = 0x1, + UAC__MIN = 0x2, + UAC__MAX = 0x3, + UAC__RES = 0x4, + UAC__MEM = 0x5, + + UAC_SET_CUR = (UAC_SET_ | UAC__CUR), + UAC_GET_CUR = (UAC_GET_ | UAC__CUR), + UAC_SET_MIN = (UAC_SET_ | UAC__MIN), + UAC_GET_MIN = (UAC_GET_ | UAC__MIN), + UAC_SET_MAX = (UAC_SET_ | UAC__MAX), + UAC_GET_MAX = (UAC_GET_ | UAC__MAX), + UAC_SET_RES = (UAC_SET_ | UAC__RES), + UAC_GET_RES = (UAC_GET_ | UAC__RES), + UAC_SET_MEM = (UAC_SET_ | UAC__MEM), + UAC_GET_MEM = (UAC_GET_ | UAC__MEM), + + UAC_GET_STAT = 0xff, + + /* A.10 Control Selector Codes */ + + /* A.10.1 Terminal Control Selectors */ + UAC_TERM_COPY_PROTECT = 0x01, + + /* A.10.2 Feature Unit Control Selectors */ + UAC_FU_MUTE = 0x01, + UAC_FU_VOLUME = 0x02, + UAC_FU_BASS = 0x03, + UAC_FU_MID = 0x04, + UAC_FU_TREBLE = 0x05, + UAC_FU_GRAPHIC_EQUALIZER = 0x06, + UAC_FU_AUTOMATIC_GAIN = 0x07, + UAC_FU_DELAY = 0x08, + UAC_FU_BASS_BOOST = 0x09, + UAC_FU_LOUDNESS = 0x0a, + + /* A.10.3.1 Up/Down-mix Processing Unit Controls Selectors */ + UAC_UD_ENABLE = 0x01, + UAC_UD_MODE_SELECT = 0x02, + + /* A.10.3.2 Dolby Prologic (tm) Processing Unit Controls Selectors */ + UAC_DP_ENABLE = 0x01, + UAC_DP_MODE_SELECT = 0x02, + + /* A.10.3.3 3D Stereo Extender Processing Unit Control Selectors */ + UAC_3D_ENABLE = 0x01, + UAC_3D_SPACE = 0x02, + + /* A.10.3.4 Reverberation Processing Unit Control Selectors */ + UAC_REVERB_ENABLE = 0x01, + UAC_REVERB_LEVEL = 0x02, + UAC_REVERB_TIME = 0x03, + UAC_REVERB_FEEDBACK = 0x04, + + /* A.10.3.5 Chorus Processing Unit Control Selectors */ + UAC_CHORUS_ENABLE = 0x01, + UAC_CHORUS_LEVEL = 0x02, + UAC_CHORUS_RATE = 0x03, + UAC_CHORUS_DEPTH = 0x04, + + /* A.10.3.6 Dynamic Range Compressor Unit Control Selectors */ + UAC_DCR_ENABLE = 0x01, + UAC_DCR_RATE = 0x02, + UAC_DCR_MAXAMPL = 0x03, + UAC_DCR_THRESHOLD = 0x04, + UAC_DCR_ATTACK_TIME = 0x05, + UAC_DCR_RELEASE_TIME = 0x06, + + /* A.10.4 Extension Unit Control Selectors */ + UAC_XU_ENABLE = 0x01, + + /* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */ + UAC_MS_HEADER = 0x01, + UAC_MIDI_IN_JACK = 0x02, + UAC_MIDI_OUT_JACK = 0x03, + + /* MIDI - A.1 MS Class-Specific Endpoint Descriptor Subtypes */ + UAC_MS_GENERAL = 0x01, + + /* Terminals - 2.1 USB Terminal Types */ + UAC_TERMINAL_UNDEFINED = 0x100, + UAC_TERMINAL_STREAMING = 0x101, + UAC_TERMINAL_VENDOR_SPEC = 0x1FF, + + + UAC_BCD_V10 = 0x100, + UAC_CHANNEL_LEFT = 0x1, + UAC_CHANNEL_RIGHT = 0x2, + UAC_OUTPUT_TERMINAL_STREAMING = 0x101, + + USB_DT_CS_DEVICE = (USB_TYPE_CLASS | USB_DESC_DEVICE), + USB_DT_CS_CONFIG = (USB_TYPE_CLASS | USB_DESC_CONFIGURATION), + USB_DT_CS_STRING = (USB_TYPE_CLASS | USB_DESC_STRING), + USB_DT_CS_INTERFACE = (USB_TYPE_CLASS | USB_DESC_INTERFACE), + USB_DT_CS_ENDPOINT = (USB_TYPE_CLASS | USB_DESC_ENDPOINT), + + /* Terminals - 2.2 Input Terminal Types */ + UAC_INPUT_TERMINAL_UNDEFINED = 0x200, + UAC_INPUT_TERMINAL_MICROPHONE = 0x201, + UAC_INPUT_TERMINAL_DESKTOP_MICROPHONE = 0x202, + UAC_INPUT_TERMINAL_PERSONAL_MICROPHONE = 0x203, + UAC_INPUT_TERMINAL_OMNI_DIR_MICROPHONE = 0x204, + UAC_INPUT_TERMINAL_MICROPHONE_ARRAY = 0x205, + UAC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY = 0x206, + + /* Terminals - 2.3 Output Terminal Types */ + UAC_OUTPUT_TERMINAL_UNDEFINED = 0x300, + UAC_OUTPUT_TERMINAL_SPEAKER = 0x301, + UAC_OUTPUT_TERMINAL_HEADPHONES = 0x302, + UAC_OUTPUT_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO = 0x303, + UAC_OUTPUT_TERMINAL_DESKTOP_SPEAKER = 0x304, + UAC_OUTPUT_TERMINAL_ROOM_SPEAKER = 0x305, + UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER = 0x306, + UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER = 0x307, + + /* Formats - A.1.1 Audio Data Format Type I Codes */ + UAC_FORMAT_TYPE_I_UNDEFINED = 0x0, + UAC_FORMAT_TYPE_I_PCM = 0x1, + UAC_FORMAT_TYPE_I_PCM8 = 0x2, + UAC_FORMAT_TYPE_I_IEEE_FLOAT = 0x3, + UAC_FORMAT_TYPE_I_ALAW = 0x4, + UAC_FORMAT_TYPE_I_MULAW = 0x5, + + /* Formats - A.2 Format Type Codes */ + UAC_FORMAT_TYPE_UNDEFINED = 0x0, + UAC_FORMAT_TYPE_I = 0x1, + UAC_FORMAT_TYPE_II = 0x2, + UAC_FORMAT_TYPE_III = 0x3, + UAC_EXT_FORMAT_TYPE_I = 0x81, + UAC_EXT_FORMAT_TYPE_II = 0x82, + UAC_EXT_FORMAT_TYPE_III = 0x83, +}; + + +/* 4.3.2 Class-Specific AC Interface Descriptor */ +struct usb_desc_uac1_ac_header { + uint8_t bLength; /* 8 + n */ + uint8_t bDescriptorType; /* USB_DT_CS_INTERFACE */ + uint8_t bDescriptorSubtype; /* UAC_MS_HEADER */ + uint16_t bcdADC; /* 0x0100 */ + uint16_t wTotalLength; /* includes Unit and Terminal desc. */ + uint8_t bInCollection; /* n */ + uint8_t baInterfaceNr[]; /* [n] */ +}; + +USB_DESC_CONST_CODE_TYPEDEF(usb_desc_uac1_ac_header) + +/* 4.5.2 Class-Specific AS Interface Descriptor */ +struct usb_desc_uac1_as_header { + uint8_t bLength; /* in bytes: 7 */ + uint8_t bDescriptorType; /* USB_DT_CS_INTERFACE */ + uint8_t bDescriptorSubtype; /* AS_GENERAL */ + uint8_t bTerminalLink; /* Terminal ID of connected Terminal */ + uint8_t bDelay; /* Delay introduced by the data path */ + uint16_t wFormatTag; /* The Audio Data Format */ +}; + +USB_DESC_CONST_CODE_TYPEDEF(usb_desc_uac1_as_header) + +struct usb_desc_uac1_output_terminal { + uint8_t bLength; /* in bytes: 9 */ + uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */ + uint8_t bDescriptorSubtype; /* OUTPUT_TERMINAL descriptor subtype */ + uint8_t bTerminalID; /* Constant uniquely terminal ID */ + uint16_t wTerminalType; /* USB Audio Terminal Types */ + uint8_t bAssocTerminal; /* ID of the Input Terminal associated */ + uint8_t bSourceID; /* ID of the connected Unit or Terminal*/ + uint8_t iTerminal; +}; + +USB_DESC_CONST_CODE_TYPEDEF(usb_desc_uac1_output_terminal) + +/* Formats - A.1.1 Audio Data Format Type I Codes */ +struct usb_desc_uac_format_type_i_continuous { + uint8_t bLength; /* in bytes: 8 + (ns * 3) */ + uint8_t bDescriptorType; /* USB_DT_CS_INTERFACE */ + uint8_t bDescriptorSubtype; /* FORMAT_TYPE */ + uint8_t bFormatType; /* FORMAT_TYPE_1 */ + uint8_t bNrChannels; /* physical channels in the stream */ + uint8_t bSubframeSize; /* */ + uint8_t bBitResolution; + uint8_t bSamFreqType; + uint8_t tLowerSamFreq[3]; + uint8_t tUpperSamFreq[3]; +}; +struct usb_desc_uac_format_type_i_discrete { + uint8_t bLength; /* in bytes: 8 + (ns * 3) */ + uint8_t bDescriptorType; /* USB_DT_CS_INTERFACE */ + uint8_t bDescriptorSubtype; /* FORMAT_TYPE */ + uint8_t bFormatType; /* FORMAT_TYPE_1 */ + uint8_t bNrChannels; /* physical channels in the stream */ + uint8_t bSubframeSize; + uint8_t bBitResolution; + uint8_t bSamFreqType; + uint8_t tSamFreq[][3]; +}; + +USB_DESC_CONST_CODE_TYPEDEF(usb_desc_uac_format_type_i_continuous) +USB_DESC_CONST_CODE_TYPEDEF(usb_desc_uac_format_type_i_discrete) + +/* 4.3.2.1 Input Terminal Descriptor */ +struct usb_desc_uac_input_terminal { + uint8_t bLength; /* in bytes: 12 */ + uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */ + uint8_t bDescriptorSubtype; /* INPUT_TERMINAL descriptor subtype */ + uint8_t bTerminalID; /* Constant uniquely terminal ID */ + uint16_t wTerminalType; /* USB Audio Terminal Types */ + uint8_t bAssocTerminal; /* ID of the Output Terminal associated */ + uint8_t bNrChannels; /* Number of logical output channels */ + uint16_t wChannelConfig; + uint8_t iChannelNames; + uint8_t iTerminal; +}; + +USB_DESC_CONST_CODE_TYPEDEF(usb_desc_uac_input_terminal) + +/* Formats - A.2 Format Type Codes */ +struct usb_desc_uac_iso_endpoint { + uint8_t bLength; /* in bytes: 7 */ + uint8_t bDescriptorType; /* USB_DT_CS_ENDPOINT */ + uint8_t bDescriptorSubtype; /* EP_GENERAL */ + uint8_t bmAttributes; + uint8_t bLockDelayUnits; + uint16_t wLockDelay; +}; + +USB_DESC_CONST_CODE_TYPEDEF(usb_desc_uac_iso_endpoint) + +/* USB_DT_ENDPOINT: Audio Endpoint descriptor */ +struct usb_desc_audio_endpoint { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; + /* NOTE: these two are _only_ in audio endpoints. */ + uint8_t bRefresh; + uint8_t bSynchAddress; +}; + +USB_DESC_CONST_CODE_TYPEDEF(usb_desc_audio_endpoint) + +/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */ +struct usb_desc_dev_qualifier { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bRESERVED; +}; + +USB_DESC_CONST_CODE_TYPEDEF(usb_desc_dev_qualifier) + +#endif /* UAC_DEFS_H */ diff --git a/common/usb_defs.h b/common/usb_defs.h new file mode 100644 index 0000000..37a7870 --- /dev/null +++ b/common/usb_defs.h @@ -0,0 +1,36 @@ +#ifndef USB_DEFS_H +#define USB_DEFS_H + +#include +#include + +// Macro to easily define typedefs for descriptor structures +#define USB_DESC_CONST_CODE_TYPEDEF(desc) \ + typedef __code const struct desc \ + desc ## _c; + +enum { + // Interface association descriptor, requires proper device descriptor + // see: USB Interface Association Descriptor Device Class Code and Use Model, 1.0 + // https://www.usb.org/sites/default/files/iadclasscode_r10.pdf + USB_DEV_CLASS_MISCELLANEOUS = 0xef, + USB_DEV_SUBCLASS_COMMON = 0x02, + USB_DEV_PROTOCOL_INTERFACE_ASSOCIATION_DESCRIPTOR = 0x01, + USB_DESC_IF_ASSOC = 0x0b, +}; + +struct usb_desc_if_assoc { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +}; + +USB_DESC_CONST_CODE_TYPEDEF(usb_desc_if_assoc) + + +#endif /* USB_DEFS_H */ diff --git a/examples/audio/Makefile b/examples/audio/Makefile new file mode 100644 index 0000000..208104d --- /dev/null +++ b/examples/audio/Makefile @@ -0,0 +1,7 @@ +TARGET = audio +LIBFX2DIR = ../../third_party/libfx2 +LIBRARIES = fx2 fx2usb fx2isrs +FLAGS = -I../../common -DDEBUG +SOURCES = main descriptors ../../common/uac + +include ../../common/common.mk diff --git a/examples/audio/descriptors.c b/examples/audio/descriptors.c new file mode 100644 index 0000000..9069cf1 --- /dev/null +++ b/examples/audio/descriptors.c @@ -0,0 +1,56 @@ +#include +#include + +#include "uac.h" + +usb_ascii_string_c usb_strings[] = { + "TimVideos.us", + "USB Audio Class example", + "Left", + "Right", +}; + +usb_desc_device_c usb_device = { + .bLength = sizeof(struct usb_desc_device), + .bDescriptorType = USB_DESC_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = USB_DEV_CLASS_MISCELLANEOUS, + .bDeviceSubClass = USB_DEV_SUBCLASS_COMMON, + .bDeviceProtocol = USB_DEV_PROTOCOL_INTERFACE_ASSOCIATION_DESCRIPTOR, + .bMaxPacketSize0 = 64, + .idVendor = VID, // VID, PID, DID defined by compiler flags depending on BOARD + .idProduct = PID, + .bcdDevice = DID, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 0, + .bNumConfigurations = 1, +}; + +usb_configuration_c usb_config = { + { + .bLength = sizeof(struct usb_desc_configuration), + .bDescriptorType = USB_DESC_CONFIGURATION, + .bNumInterfaces = UAC_NUM_INTERFACES, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = USB_ATTR_RESERVED_1, + .bMaxPower = 250, // 500mA + }, + { + UAC_DESCRIPTORS_LIST + { 0 } + } +}; + +usb_configuration_set_c usb_configs[] = { + &usb_config, +}; + +usb_descriptor_set_c usb_descriptor_set = { + .device = &usb_device, + .config_count = ARRAYSIZE(usb_configs), + .configs = usb_configs, + .string_count = ARRAYSIZE(usb_strings), + .strings = usb_strings, +}; diff --git a/examples/audio/main.c b/examples/audio/main.c new file mode 100644 index 0000000..5e136f5 --- /dev/null +++ b/examples/audio/main.c @@ -0,0 +1,52 @@ +#include +#include +#include + +#include "uac.h" + +int main() { + // Run core at 48 MHz fCLK. + CPUCS = _CLKSPD1; + + // Configure descriptors + { + __xdata struct uac_configuration config = { + .if_num_ctrl = 0, // interface numbers start from 0 + .ep_addr_streaming = 2, // use EP2 for streaming interface + .i_str_channel_left = 3, + }; + uac_config(&config); + } + + // Configure UAC endpoint: 512-byte, double buffered, ISOCHRONOUS IN + SYNCDELAY; + EP2CFG = _VALID|_DIR|_TYPE0|_BUF1; + + // Re-enumerate, to make sure our descriptors are picked up correctly. + usb_init(/*disconnect=*/true); + + while (1) { + + } +} + +/*** Reimplemented libfx2 USB handlers ****************************************/ + +// USB setup commands +void handle_usb_setup(__xdata struct usb_req_setup *req) { + STALL_EP0(); // not handled +} + +// Set active interface _alternate setting_ +bool handle_usb_set_interface(uint8_t interface, uint8_t alt_setting) { + if (uac_handle_usb_set_interface(interface, alt_setting)) + return true; + return false; // not handled +} + +// Set current interface _alternate setting_ +void handle_usb_get_interface(uint8_t interface) { + if (uac_handle_usb_get_interface(interface)) + return; + STALL_EP0(); // not handled +} diff --git a/examples/common/uac.d b/examples/common/uac.d new file mode 100644 index 0000000..1ec5a17 --- /dev/null +++ b/examples/common/uac.d @@ -0,0 +1,7 @@ +build/../../common/uac.rel: ../../common/uac.c ../../common/uac.h \ + ../../third_party/libfx2/firmware/library/include/fx2usb.h \ + ../../third_party/libfx2/firmware/library/include/fx2regs.h \ + ../../third_party/libfx2/firmware/library/include/fx2ints.h \ + ../../third_party/libfx2/firmware/library/include/usb.h \ + ../../common/uac_defs.h ../../common/usb_defs.h \ + ../../third_party/libfx2/firmware/library/include/fx2lib.h From 0a4652855d897498c72f308098e00fb468cca066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Tue, 7 Jan 2020 13:58:38 +0100 Subject: [PATCH 6/9] add audio example readme --- examples/audio/README.md | 16 ++++++++++++++++ examples/common/uac.d | 7 ------- 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 examples/audio/README.md delete mode 100644 examples/common/uac.d diff --git a/examples/audio/README.md b/examples/audio/README.md new file mode 100644 index 0000000..801638b --- /dev/null +++ b/examples/audio/README.md @@ -0,0 +1,16 @@ +# USB audio example + +This is an example application implementing USB audio class (UAC) (see: [Universal Serial Bus Device Class Definition for Audio Devices](https://usb.org/)). + +Device descriptor uses class/subclass/protocol compatible with Interface Association Descriptors +(see: [USB Interface Association Descriptor Device Class Code and Use Model, 1.0](https://www.usb.org/sites/default/files/iadclasscode_r10.pdf)). + +There are two interfaces: + +* Audio control interface: 0 endpoints - no need for interrupt endpoint + +* Audio streaming interface (with alternate settings 0 and 1) + * alternate setting 0: no endpoints, host can use it to disable audio in case of bandwidth problems + * alternate setting 1: single isochronous endpoint + +The application provides simple audio topology consisting of a single input terminal and single output terminal. diff --git a/examples/common/uac.d b/examples/common/uac.d deleted file mode 100644 index 1ec5a17..0000000 --- a/examples/common/uac.d +++ /dev/null @@ -1,7 +0,0 @@ -build/../../common/uac.rel: ../../common/uac.c ../../common/uac.h \ - ../../third_party/libfx2/firmware/library/include/fx2usb.h \ - ../../third_party/libfx2/firmware/library/include/fx2regs.h \ - ../../third_party/libfx2/firmware/library/include/fx2ints.h \ - ../../third_party/libfx2/firmware/library/include/usb.h \ - ../../common/uac_defs.h ../../common/usb_defs.h \ - ../../third_party/libfx2/firmware/library/include/fx2lib.h From 3af43669de9eed4bf608dc3c09c10bb6d1f221f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Wed, 8 Jan 2020 16:04:10 +0100 Subject: [PATCH 7/9] add common.mk dependecy to automatically build libfx2 --- common/common.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/common.mk b/common/common.mk index 8038713..5d3abfa 100644 --- a/common/common.mk +++ b/common/common.mk @@ -38,3 +38,6 @@ LIBFX2DIR ?= ../third_party/libfx2 # variable required by libfx2 build system LIBFX2 = $(LIBFX2DIR)/firmware/library include $(LIBFX2)/fx2rules.mk + +# force proper dependecy to automatically build libfx2 +$(LIBFX2)/lib/$(MODEL)/fx2.lib: $(LIBFX2)/.stamp From 4e54a46f87fdcadbb5fa4bcb13938e7ff7e71759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Wed, 8 Jan 2020 16:28:19 +0100 Subject: [PATCH 8/9] travis: build only the audio example --- .travis.yml | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 76e0569..1870267 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ addons: install: - export BOARD="$B" && echo "BOARD='$BOARD'" - - export TARGETS="$T" && echo "TARGETS='$TARGETS'" + - export DIR="$D" && echo "DIR='$DIR'" - make conda - export PATH=$PWD/conda/bin:$PATH - which sdcc @@ -22,30 +22,12 @@ jobs: fail_fast: true include: #----------------------------------------- - # Video targets + # audio #----------------------------------------- - stage: Build - env: B=opsis T="firmware-fx2" + env: B=opsis D="examples/audio" - stage: Build - env: B=atlys T="firmware-fx2" - - #----------------------------------------- - # Audio targets - #----------------------------------------- - - stage: Build - env: B=opsis T="firmware-audio-fx2" - - stage: Build - env: B=atlys T="firmware-audio-fx2" - - stage: Build - env: B=fx2miniboard T="firmware-audio-fx2" - - #----------------------------------------- - # Unconfigured targets - #----------------------------------------- - - stage: Build - env: B=opsis T="firmware-unconfigured" - - stage: Build - env: B=atlys T="firmware-unconfigured" + env: B=atlys D="examples/audio" #----------------------------------------- # Build and deploy docs From 35d56d8db26cb3c1258eb5b0e1a38520a10931b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Wed, 8 Jan 2020 16:40:51 +0100 Subject: [PATCH 9/9] travis: fix make command --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1870267..555bad7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ install: - ./.travis/setup.sh script: - - make $TARGETS + - make -C $DIR jobs: fail_fast: true