summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2012-09-22 12:54:17 +0200
committerVegard Storheil Eriksen <zyp@jvnv.net>2012-09-22 12:54:17 +0200
commitd1ea6b91d1441f0bf423c2d27339b0386300a295 (patch)
treedffd33a50715fa0904247b6850001e5fe0929cee
parent842821a118feeabd201ebcda46154cdb9b305187 (diff)
Made device enumerate as USB Audio device.
m---------laks0
-rw-r--r--main.cpp157
2 files changed, 94 insertions, 63 deletions
diff --git a/laks b/laks
-Subproject 89baa2a3f6a301a608507f4bf6cfc741e5e06aa
+Subproject 95729b7fd4de6704823ab8033593abe35213491
diff --git a/main.cpp b/main.cpp
index 58cc167..4c3b661 100644
--- a/main.cpp
+++ b/main.cpp
@@ -4,112 +4,145 @@
#include <usb/usb.h>
#include <usb/descriptor.h>
+struct AS_General_desc {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bDescriptorSubType;
+ uint8_t bTerminalLink;
+ uint8_t bDelay;
+ uint16_t wFormatTag;
+} __attribute__((packed));
+
+constexpr AS_General_desc as_general_desc(
+ uint8_t bTerminalLink,
+ uint8_t bDelay,
+ uint16_t wFormatTag
+ ) {
+
+ return {
+ sizeof(AS_General_desc),
+ 0x24,
+ 0x01,
+ bTerminalLink,
+ bDelay,
+ wFormatTag
+ };
+}
+
+template <uint32_t S>
+struct foo_t {
+ uint8_t a[S];
+} __attribute__((packed));
+
+const foo_t<43> acd = {{
+ 9, 36, 1, 0,1, 43,0, 1, 1,
+ 12, 36, 2, 1, 1,1, 0, 2, 3,0, 0, 0,
+ 13, 36, 6, 13, 1, 2, 1, 2, 2, 0, 2, 0, 0,
+ 9, 36, 3, 3, 1,3, 0, 13, 0
+}};
+
+const foo_t<11> asfd = {{11, 36, 2, 1, 2, 2, 16, 1, 48000 & 0xff, (48000 >> 8) & 0xff, 48000 >> 16}};
+
+const foo_t<7> aced = {{7, 37, 1, 1, 0, 0, 0}};
+
auto dev_desc = device_desc(0x200, 0, 0, 0, 64, 0x1234, 0x5678, 0, 0, 0, 0, 1);
auto conf_desc = configuration_desc(2, 1, 0, 0xc0, 0,
- // CDC ACM control
- interface_desc(0, 0, 1, 0x02, 0x02, 0x01, 0,
- endpoint_desc(0x82, 0x03, 16, 255),
- cdc_header_desc(0x110),
- cdc_call_management_desc(0, 1),
- cdc_acm_desc(2),
- cdc_union_desc(0, 1)
+ // AudioControl
+ interface_desc(0, 0, 0, 0x01, 0x01, 0x00, 0,
+ acd
),
- // CDC ACM data
- interface_desc(1, 0, 2, 0x0a, 0x00, 0x00, 0,
- endpoint_desc(0x81, 0x02, 64, 0), // IN
- endpoint_desc(0x01, 0x02, 64, 0) // OUT
+ // AudioStreaming
+ interface_desc(1, 0, 0, 0x01, 0x02, 0x00, 0),
+ interface_desc(1, 1, 1, 0x01, 0x02, 0x00, 0,
+ as_general_desc(1, 1, 1),
+ asfd,
+ endpoint_desc(0x01, 0x09, 256, 1),
+ aced
)
);
desc_t dev_desc_p = {sizeof(dev_desc), (void*)&dev_desc};
desc_t conf_desc_p = {sizeof(conf_desc), (void*)&conf_desc};
-#if defined(STM32F1)
-// Maple mini.
-
-Pin& usb_disc = PB9;
-Pin& usb_dm = PA11;
-Pin& usb_dp = PA12;
-
-Pin& led1 = PB1;
-
-USB_f1 usb(USB, dev_desc_p, conf_desc_p);
-
-#elif defined(STM32F4)
-// Generic F4.
-
Pin& usb_vbus = PA9;
Pin& usb_dm = PA11;
Pin& usb_dp = PA12;
-Pin& led1 = PA4;
-
USB_otg usb(OTG_FS, dev_desc_p, conf_desc_p);
-#endif
-
-class USB_CDC_ACM : public USB_class_driver {
+class USB_Audio : public USB_class_driver {
private:
- uint32_t buf[16];
+ USB_generic& usb;
public:
+ USB_Audio(USB_generic& usbd) : usb(usbd) {
+ usb.register_driver(this);
+ }
protected:
virtual SetupStatus handle_setup(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) {
- if(bmRequestType == 0x21 && bRequest == 0x20) {
+ if(bmRequestType == 0xa1 && bRequest == 0x81) {
+ uint32_t nullw = 0;
+ usb.write(0, &nullw, wLength);
return SetupStatus::Ok;
}
- if(bmRequestType == 0x21 && bRequest == 0x22) {
- usb.write(0, nullptr, 0);
+ if(bmRequestType == 0xa1 && bRequest == 0x82) {
+ uint32_t nullw = 0;
+ usb.write(0, &nullw, wLength);
+ return SetupStatus::Ok;
+ }
+
+ if(bmRequestType == 0xa1 && bRequest == 0x83) {
+ uint32_t nullw = 0;
+ usb.write(0, &nullw, wLength);
+ return SetupStatus::Ok;
+ }
+
+ if(bmRequestType == 0xa1 && bRequest == 0x84) {
+ uint32_t nullw = 0;
+ usb.write(0, &nullw, wLength);
+ return SetupStatus::Ok;
+ }
+
+ if(bmRequestType == 0x21 && bRequest == 0x01) {
+ return SetupStatus::Ok;
+ }
+
+ if(bmRequestType == 0x22 && bRequest == 0x01) {
return SetupStatus::Ok;
}
return SetupStatus::Unhandled;
}
+ virtual void handle_set_configuration(uint8_t configuration) {
+ if(configuration) {
+ usb.register_out_handler(this, 1);
+ usb.hw_conf_ep(0x01, Isochronous, 256);
+ }
+ }
+
virtual void handle_out(uint8_t ep, uint32_t len) {
if(ep == 0) {
usb.write(0, nullptr, 0);
+
} else if(ep == 1) {
- uint32_t r_len = usb.read(ep, buf, len);
- if(r_len) {
- led1.toggle();
- usb.write(1, buf, r_len);
- }
+ usb_rblog.log("Received audio frame with %d bytes.", len);
+ //uint32_t r_len = usb.read(ep, buf, len);
}
}
};
-USB_CDC_ACM usb_cdc_acm;
+USB_Audio usb_audio(usb);
int main() {
- #if defined(STM32F1)
- // Initialize system timer.
- STK.LOAD = 72000000 / 8 / 1000; // 1000 Hz.
- STK.CTRL = 0x03;
-
- RCC.enable(RCC.AFIO);
- RCC.enable(RCC.GPIOA);
- RCC.enable(RCC.GPIOB);
-
- led1.set_mode(Pin::Output);
-
- usb_dm.set_mode(Pin::AF);
- usb_dp.set_mode(Pin::AF);
- usb_disc.set_mode(Pin::Output);
- usb_disc.off();
-
- RCC.enable(RCC.USB);
- #elif defined(STM32F4)
// Initialize system timer.
STK.LOAD = 168000000 / 8 / 1000; // 1000 Hz.
STK.CTRL = 0x03;
RCC.enable(RCC.GPIOA);
- led1.set_mode(Pin::Output);
-
usb_vbus.set_mode(Pin::Input);
usb_dm.set_mode(Pin::AF);
usb_dm.set_af(10);
@@ -117,11 +150,9 @@ int main() {
usb_dp.set_af(10);
RCC.enable(RCC.OTGFS);
- #endif
+ usb.set_rxfifo_size(512);
usb.init();
- usb.register_control_handler(&usb_cdc_acm);
- usb.register_out_handler(&usb_cdc_acm, 1);
while(1) {
usb.process();