diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2012-09-22 12:54:17 +0200 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2012-09-22 12:54:17 +0200 |
commit | d1ea6b91d1441f0bf423c2d27339b0386300a295 (patch) | |
tree | dffd33a50715fa0904247b6850001e5fe0929cee | |
parent | 842821a118feeabd201ebcda46154cdb9b305187 (diff) |
Made device enumerate as USB Audio device.
m--------- | laks | 0 | ||||
-rw-r--r-- | main.cpp | 157 |
2 files changed, 94 insertions, 63 deletions
diff --git a/laks b/laks -Subproject 89baa2a3f6a301a608507f4bf6cfc741e5e06aa +Subproject 95729b7fd4de6704823ab8033593abe35213491 @@ -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(); |