BaN 0 5 мая, 2013 Опубликовано 5 мая, 2013 (изменено) · Жалоба Никак не могу понять, как работать с изохронными конечными точками в libusb-win32-1.2.6.0. Микроконтроллер STM32F205RBT6. Взял за основу пример USB Audio от ST из STM32_USB-Host-Device_Lib_V2.1.0. Убрал из него изохронную OUT конечную точку, сделал дескриптор USB-микрофона из: http://www.usb.org/developers/devclass_docs/audio10.pdf /* USB AUDIO device Configuration Descriptor */ static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE] = { /* USB Microphone Configuration Descriptor */ 0x09,//sizeof(USB_CFG_DSC), // Size of this descriptor in bytes USB_CONFIGURATION_DESCRIPTOR_TYPE, // CONFIGURATION descriptor type LOBYTE(AUDIO_CONFIG_DESC_SIZE), /* wTotalLength 109 bytes*/ HIBYTE(AUDIO_CONFIG_DESC_SIZE), 2, // Number of interfaces in this cfg 1, // Index value of this configuration 0, // Configuration string index 0x80, // Attributes, see usb_device.h 50, // Max power consumption (2X mA) /* USB Microphone Standard AC Interface Descriptor */ 0x09,//sizeof(USB_INTF_DSC), // Size of this descriptor in bytes USB_INTERFACE_DESCRIPTOR_TYPE, // INTERFACE descriptor type 0x00, // Interface Number 0x00, // Alternate Setting Number 0x00, // Number of endpoints in this intf USB_DEVICE_CLASS_AUDIO, // Class code AUDIO_SUBCLASS_AUDIOCONTROL, // Subclass code 0x00, // Protocol code 0x00, // Interface string index /* USB Microphone Class-specific AC Interface Descriptor */ 0x09, // Size of this descriptor, in bytes. AUDIO_INTERFACE_DESCRIPTOR_TYPE, // CS_INTERFACE Descriptor Type AUDIO_CONTROL_HEADER, // HEADER descriptor subtype 0x00,0x01, // Audio Device compliant to the USB Audio specification version 1.00 0x1E,0x00, // Total number of bytes returned for the class-specific AudioControl interface descriptor. // Includes the combined length of this descriptor header and all Unit and Terminal descriptors. 0x01, // The number of AudioStreaming interfaces in the Audio Interface Collection to which this AudioControl interface belongs 0x01, // AudioStreaming interface 1 belongs to this AudioControl interface. /*USB Microphone Input Terminal Descriptor */ 0x0C, // Size of the descriptor, in bytes AUDIO_INTERFACE_DESCRIPTOR_TYPE, // CS_INTERFACE Descriptor Type AUDIO_CONTROL_INPUT_TERMINAL, // INPUT_TERMINAL descriptor subtype 0x01, // ID of this Terminal. 0x01,0x02, // Terminal is Microphone (0x01,0x02) 0x00, // No association 0x01, // One channel 0x00,0x00, // Mono sets no position bits 0x00, // Unused. 0x00, // Unused. /* USB Microphone Output Terminal Descriptor */ 0x09, // Size of the descriptor, in bytes (bLength) AUDIO_INTERFACE_DESCRIPTOR_TYPE, // CS_INTERFACE Descriptor Type (bDescriptorType) AUDIO_CONTROL_OUTPUT_TERMINAL, // OUTPUT_TERMINAL descriptor subtype (bDescriptorSubtype) 0x02, // ID of this Terminal. (bTerminalID) 0x01, 0x01, // USB Streaming. (wTerminalType 0x00, // unused (bAssocTerminal) 0x01, // From Input Terminal.(bSourceID) 0x00, // unused (iTerminal) /* USB Microphone Standard AS Interface Descriptor (Alt. Set. 0) */ 0x09, // Size of the descriptor, in bytes (bLength) USB_INTERFACE_DESCRIPTOR_TYPE, // INTERFACE descriptor type (bDescriptorType) 0x01, // Index of this interface. (bInterfaceNumber) 0x00, // Index of this alternate setting. (bAlternateSetting) 0x00, // 0 endpoints. (bNumEndpoints) USB_DEVICE_CLASS_AUDIO, // AUDIO (bInterfaceClass) AUDIO_SUBCLASS_AUDIOSTREAMING, // AUDIO_STREAMING (bInterfaceSubclass) 0x00, // Unused. (bInterfaceProtocol) 0x00, // Unused. (iInterface) /* USB Microphone Standard AS Interface Descriptor (Alt. Set. 1) */ 0x09, // Size of the descriptor, in bytes (bLength) USB_INTERFACE_DESCRIPTOR_TYPE, // INTERFACE descriptor type (bDescriptorType) 0x01, // Index of this interface. (bInterfaceNumber) 0x01, // Index of this alternate setting. (bAlternateSetting) 0x01, // 1 endpoint (bNumEndpoints) USB_DEVICE_CLASS_AUDIO, // AUDIO (bInterfaceClass) AUDIO_SUBCLASS_AUDIOSTREAMING, // AUDIO_STREAMING (bInterfaceSubclass) 0x00, // Unused. (bInterfaceProtocol) 0x00, // Unused. (iInterface) /* USB Microphone Class-specific AS General Interface Descriptor */ 0x07, // Size of the descriptor, in bytes (bLength) AUDIO_INTERFACE_DESCRIPTOR_TYPE, // CS_INTERFACE Descriptor Type (bDescriptorType) AUDIO_STREAMING_GENERAL, // GENERAL subtype (bDescriptorSubtype) 0x02, // Unit ID of the Output Terminal.(bTerminalLink) 0x01, // Interface delay. (bDelay) 0x01,0x00, // PCM Format (wFormatTag) /* USB Microphone Type I Format Type Descriptor */ 0x0B, // Size of the descriptor, in bytes (bLength) AUDIO_INTERFACE_DESCRIPTOR_TYPE, // CS_INTERFACE Descriptor Type (bDescriptorType) AUDIO_STREAMING_FORMAT_TYPE, // FORMAT_TYPE subtype. (bDescriptorSubtype) 0x01, // FORMAT_TYPE_I. (bFormatType) 0x01, // One channel.(bNrChannels) 0x02, // Two bytes per audio subframe.(bSubFrameSize) 0x10, // 16 bits per sample.(bBitResolution) 0x01, // One frequency supported. (bSamFreqType) 0x40,0x1F,0x00, // 8000Hz. (tSamFreq) /* USB Microphone Standard Endpoint Descriptor */ 0x09, // Size of the descriptor, in bytes (bLength) 0x05, // ENDPOINT descriptor (bDescriptorType) 0x81, // IN Endpoint 1. (bEndpointAddress) 0x01, // Isochronous, not shared. (bmAttributes) (tx_buf_len&0xFF),((tx_buf_len>>8)&0xFF), // 16 bytes per packet (wMaxPacketSize) 0x01, // One packet per frame.(bInterval) 0x00, // Unused. (bRefresh) 0x00, // Unused. (bSynchAddress) /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor*/ 0x07, // Size of the descriptor, in bytes (bLength) AUDIO_ENDPOINT_DESCRIPTOR_TYPE, // CS_ENDPOINT Descriptor Type (bDescriptorType) AUDIO_ENDPOINT_GENERAL, // GENERAL subtype. (bDescriptorSubtype) 0x00, // No sampling frequency control, no pitch control, no packet padding.(bmAttributes) 0x00, // Unused. (bLockDelayUnits) 0x00,0x00, // Unused. (wLockDelay) }; Добавил изохронную IN конечную точку. Сделал пробную непрерывную передачу буфера на ПК: #define RX_FIFO_FS_SIZE 47 #define TX0_FIFO_FS_SIZE 17 #define TX1_FIFO_FS_SIZE 256 #define TX2_FIFO_FS_SIZE 0 #define TX3_FIFO_FS_SIZE 0 #define tx_buf_len 128 uint8_t tx_buf[tx_buf_len]; int main(void) { // Забиваю в буфер первые данные for (uint32_t i = 0; i < tx_buf_len;) { tx_buf[i++] = 0xAA; } ... USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &AUDIO_cb, &USR_cb); while(1); } static uint8_t usbd_audio_Init (void *pdev, uint8_t cfgidx) { /* Open EP IN */ DCD_EP_Open(pdev, 0x81, tx_buf_len, USB_OTG_EP_ISOC); // Отправляем первый пакет в TxFIFO DCD_EP_Tx (pdev, 0x81, tx_buf, tx_buf_len); return USBD_OK; } static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum) { if (epnum == 0x01) { // Забиваем буфер номером отправляемого пакета static uint32_t cnt = 0; for (uint32_t i = 0; i < tx_buf_len;) { tx_buf[i++] = ((uint8_t*)&(cnt))[3]; tx_buf[i++] = ((uint8_t*)&(cnt))[2]; tx_buf[i++] = ((uint8_t*)&(cnt))[1]; tx_buf[i++] = ((uint8_t*)&(cnt))[0]; } cnt++; // Отправляем новый пакет в TxFIFO DCD_EP_Tx (pdev, 0x81, tx_buf, tx_buf_len); } return USBD_OK; } В итоге, устройство нормально определяется, присоединяюсь к конечной точке, данные приходят. Но вот только приходят они каким-то непонятным образом. Программа на ПК: #include <stdio.h> #include <lusb0_usb.h> #define VENDOR_ID 0x0483 #define PRODUCT_ID 0x5730 #define INTERFACE 1 #define PKT_SIZE 128 #define ISO_IN_EP 0x81 FILE * file; usb_dev_handle *find_testdev_isoc(); usb_dev_handle* setup_libusb_access() { usb_dev_handle *testdev_isoc; usb_set_debug(4); usb_init(); usb_find_busses(); usb_find_devices(); if(!(testdev_isoc = find_testdev_isoc())) { printf("Couldn't find the mouse, Exiting\n"); return NULL; } if (usb_set_configuration(testdev_isoc, 1) < 0) { printf("Could not set configuration 1\n"); return NULL; } if (usb_claim_interface(testdev_isoc, INTERFACE) < 0) { printf("Could not claim interface %d\n", INTERFACE); return NULL; } usb_set_altinterface(testdev_isoc, 1); return testdev_isoc; } usb_dev_handle *find_testdev_isoc() { struct usb_bus *bus; struct usb_device *dev; for (bus = usb_busses; bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == VENDOR_ID && dev->descriptor.idProduct == PRODUCT_ID ) { usb_dev_handle *handle; printf("testdev_isoc with Vendor Id: %x and Product Id: %x found.\n", VENDOR_ID, PRODUCT_ID); if (!(handle = usb_open(dev))) { printf("Could not open USB device\n"); return NULL; } return handle; } } } return NULL; } void test_isochronous_async(usb_dev_handle *dev) { unsigned char buf0[255*PKT_SIZE]; int i; void *context0 = NULL; usb_isochronous_setup_async(dev, &context0, ISO_IN_EP,PKT_SIZE); for(i = 0; i < 50; i++) { int len; usb_submit_async(context0, (char*)buf0, sizeof(buf0)); len = usb_reap_async(context0, 5000); if (len > 0) { fwrite (buf0 , 1 ,len , file ); } } usb_free_async(&context0); } int main(void) { file = fopen("log.txt", "wb"); if (file == 0) { printf("Can not open file\n"); return(0); } usb_dev_handle *testdev_isoc; if ((testdev_isoc = setup_libusb_access()) == NULL) { exit(-1); } test_isochronous_async(testdev_isoc); /* release interface */ usb_release_interface(testdev_isoc, 1); usb_close(testdev_isoc); fclose(file); return 0; } Первый раз буфер заполняется нормально, второй раз уже какая-то ерунда: в начале с разрывами в буфере часть данных, которые были приняты в первый раз и немного новых данных под конец, третий и последующие разы в буфер записывается часть данных из конца второй передачи и часть новых данных. Приложил лог. Видимо, я что-то не так делаю при работе с libusb, но так и не могу понять как правильно, документации на libusb особо никакой нет. Может кто уже реализовывал подобное, куда копать? log.txt Изменено 5 мая, 2013 пользователем BaN Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nikkov 0 6 мая, 2013 Опубликовано 6 мая, 2013 · Жалоба Никак не могу понять, как работать с изохронными конечными точками в libusb-win32-1.2.6.0. Видимо, я что-то не так делаю при работе с libusb, но так и не могу понять как правильно, документации на libusb особо никакой нет. Может кто уже реализовывал подобное, куда копать? Я делал нечто похожее правда для HS и на libusbk, но начинал для FS и на libusb. Сейчас не помню из-за каких конкретно проблем с изохронными передачами в libusb перешел на libusbk, но с последней работа пошла гораздо бодрее. Да, кстати, а зачем использовать libusb для обычного USB Audio? Чем стандартный Win драйвер не угодил? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BaN 0 6 мая, 2013 Опубликовано 6 мая, 2013 · Жалоба Я делал нечто похожее правда для HS и на libusbk, но начинал для FS и на libusb. Сейчас не помню из-за каких конкретно проблем с изохронными передачами в libusb перешел на libusbk, но с последней работа пошла гораздо бодрее. Да, кстати, а зачем использовать libusb для обычного USB Audio? Чем стандартный Win драйвер не угодил? Хм, что-то я об очевидном не подумал, попробую использовать его. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BaN 0 7 мая, 2013 Опубликовано 7 мая, 2013 (изменено) · Жалоба Сделал передачу от устройства потока 16-бит 48кГц 1 канал с дескриптором: #define tx_buf_len 92 /* USB AUDIO device Configuration Descriptor */ static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE] = { /* USB Microphone Configuration Descriptor */ 0x09,//sizeof(USB_CFG_DSC), // Size of this descriptor in bytes USB_CONFIGURATION_DESCRIPTOR_TYPE, // CONFIGURATION descriptor type LOBYTE(AUDIO_CONFIG_DESC_SIZE), /* wTotalLength 109 bytes*/ HIBYTE(AUDIO_CONFIG_DESC_SIZE), 2, // Number of interfaces in this cfg 1, // Index value of this configuration 0, // Configuration string index 0x80, // Attributes, see usb_device.h 50, // Max power consumption (2X mA) /* USB Microphone Standard AC Interface Descriptor */ 0x09,//sizeof(USB_INTF_DSC), // Size of this descriptor in bytes USB_INTERFACE_DESCRIPTOR_TYPE, // INTERFACE descriptor type 0x00, // Interface Number 0x00, // Alternate Setting Number 0x00, // Number of endpoints in this intf USB_DEVICE_CLASS_AUDIO, // Class code AUDIO_SUBCLASS_AUDIOCONTROL, // Subclass code 0x00, // Protocol code 0x00, // Interface string index /* USB Microphone Class-specific AC Interface Descriptor */ 0x09, // Size of this descriptor, in bytes. AUDIO_INTERFACE_DESCRIPTOR_TYPE, // CS_INTERFACE Descriptor Type AUDIO_CONTROL_HEADER, // HEADER descriptor subtype 0x00,0x01, // Audio Device compliant to the USB Audio specification version 1.00 0x1E,0x00, // Total number of bytes returned for the class-specific AudioControl interface descriptor. // Includes the combined length of this descriptor header and all Unit and Terminal descriptors. 0x01, // The number of AudioStreaming interfaces in the Audio Interface Collection to which this AudioControl interface belongs 0x01, // AudioStreaming interface 1 belongs to this AudioControl interface. /*USB Microphone Input Terminal Descriptor */ 0x0C, // Size of the descriptor, in bytes AUDIO_INTERFACE_DESCRIPTOR_TYPE, // CS_INTERFACE Descriptor Type AUDIO_CONTROL_INPUT_TERMINAL, // INPUT_TERMINAL descriptor subtype 0x01, // ID of this Terminal. 0x01,0x02, // Terminal is Microphone (0x01,0x02) 0x00, // No association 0x06, // One channel 0x00,0x00, // Mono sets no position bits 0x00, // Unused. 0x00, // Unused. /* USB Microphone Output Terminal Descriptor */ 0x09, // Size of the descriptor, in bytes (bLength) AUDIO_INTERFACE_DESCRIPTOR_TYPE, // CS_INTERFACE Descriptor Type (bDescriptorType) AUDIO_CONTROL_OUTPUT_TERMINAL, // OUTPUT_TERMINAL descriptor subtype (bDescriptorSubtype) 0x02, // ID of this Terminal. (bTerminalID) 0x01, 0x01, // USB Streaming. (wTerminalType 0x00, // unused (bAssocTerminal) 0x01, // From Input Terminal.(bSourceID) 0x00, // unused (iTerminal) /* USB Microphone Standard AS Interface Descriptor (Alt. Set. 0) */ 0x09, // Size of the descriptor, in bytes (bLength) USB_INTERFACE_DESCRIPTOR_TYPE, // INTERFACE descriptor type (bDescriptorType) 0x01, // Index of this interface. (bInterfaceNumber) 0x00, // Index of this alternate setting. (bAlternateSetting) 0x00, // 0 endpoints. (bNumEndpoints) USB_DEVICE_CLASS_AUDIO, // AUDIO (bInterfaceClass) AUDIO_SUBCLASS_AUDIOSTREAMING, // AUDIO_STREAMING (bInterfaceSubclass) 0x00, // Unused. (bInterfaceProtocol) 0x00, // Unused. (iInterface) /* USB Microphone Standard AS Interface Descriptor (Alt. Set. 1) */ 0x09, // Size of the descriptor, in bytes (bLength) USB_INTERFACE_DESCRIPTOR_TYPE, // INTERFACE descriptor type (bDescriptorType) 0x01, // Index of this interface. (bInterfaceNumber) 0x01, // Index of this alternate setting. (bAlternateSetting) 0x01, // 1 endpoint (bNumEndpoints) USB_DEVICE_CLASS_AUDIO, // AUDIO (bInterfaceClass) AUDIO_SUBCLASS_AUDIOSTREAMING, // AUDIO_STREAMING (bInterfaceSubclass) 0x00, // Unused. (bInterfaceProtocol) 0x00, // Unused. (iInterface) /* USB Microphone Class-specific AS General Interface Descriptor */ 0x07, // Size of the descriptor, in bytes (bLength) AUDIO_INTERFACE_DESCRIPTOR_TYPE, // CS_INTERFACE Descriptor Type (bDescriptorType) AUDIO_STREAMING_GENERAL, // GENERAL subtype (bDescriptorSubtype) 0x02, // Unit ID of the Output Terminal.(bTerminalLink) 0x01, // Interface delay. (bDelay) 0x01,0x00, // PCM Format (wFormatTag) /* USB Microphone Type I Format Type Descriptor */ 0x0B, // Size of the descriptor, in bytes (bLength) AUDIO_INTERFACE_DESCRIPTOR_TYPE, // CS_INTERFACE Descriptor Type (bDescriptorType) AUDIO_STREAMING_FORMAT_TYPE, // FORMAT_TYPE subtype. (bDescriptorSubtype) 0x01, // FORMAT_TYPE_I. (bFormatType) 0x06, // One channel.(bNrChannels) 0x03, // Two bytes per audio subframe.(bSubFrameSize) 24, // 16 bits per sample.(bBitResolution) 0x01, // One frequency supported. (bSamFreqType) 0x80,0xBB,0x00, // 48000Hz. (tSamFreq) /* USB Microphone Standard Endpoint Descriptor */ 0x09, // Size of the descriptor, in bytes (bLength) 0x05, // ENDPOINT descriptor (bDescriptorType) 0x81, // IN Endpoint 1. (bEndpointAddress) 0x01, // Isochronous, not shared. (bmAttributes) (tx_buf_len&0xFF),((tx_buf_len>>8)&0xFF), // 16 bytes per packet (wMaxPacketSize) 0x01, // One packet per frame.(bInterval) 0x00, // Unused. (bRefresh) 0x00, // Unused. (bSynchAddress) /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor*/ 0x07, // Size of the descriptor, in bytes (bLength) AUDIO_ENDPOINT_DESCRIPTOR_TYPE, // CS_ENDPOINT Descriptor Type (bDescriptorType) AUDIO_ENDPOINT_GENERAL, // GENERAL subtype. (bDescriptorSubtype) 0x00, // No sampling frequency control, no pitch control, no packet padding.(bmAttributes) 0x00, // Unused. (bLockDelayUnits) 0x00,0x00, // Unused. (wLockDelay) }; Сначала принимал данные через Sound Forge, почему-то данные принимались в виде меандра с периодом 1 секунда, хотя, судя по USBlyzer данные принимались нормально и шли правильные (пакет забивался одинаковыми байтами с его номером, после чего номер инкрементировался), а принимались слова 0x7FFF и 0x8000 (полсекунды все 0x7FFF, полсекунды все 0x8000). Потом я взял библиотеку SDL и пример: http://burningsmell.org/sdl_audioin/ И то же и самое и осталось, в USBlyzer вижу всё нормально, а в потоке колбека идут полсекунды все 0x7FFF, полсекунды все 0x8000. И после этого решил забить на стандартные драйвера, т.к., ко всему прочему, SDL поддерживала только 16-битные семплы и до 2-х каналов, а мне нужно было получать данные с 6-ти каналов 24-битных семплов 48кГц, что никак не получится сделать даже использовав 2 16-битных канала с 192кГц частотой. После этого, решил взять libusbk. Скачал, поставил, подправил исходники примера xfer-iso-read, скомпилировал tdm64, запустил и данные начали приниматься нормально с первого раза и без проблем. UPD: Хотя нет, с стандартными драйверами не совсем такая ситуация была, принималось как-то так: LSB 16-битные семплы, размер этого блока бывает разным, количество 0x8000 и 0x7FFF тоже разное от блока к блоку, но примерно одинаковое, но переход от 0x8000 к 0x7FFF одинаков. http://pastebin.com/CvxgnbHm Изменено 7 мая, 2013 пользователем BaN Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ander0 0 14 октября, 2014 Опубликовано 14 октября, 2014 · Жалоба Я тоже пытаюсь запустить аудио на stm32f205. BaN, можете выложить свои исходники? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BaN 0 19 октября, 2014 Опубликовано 19 октября, 2014 · Жалоба Проект Eclipse+gcc с USB ISO: IKAIS_ADC.rar Программа под Windows для приема данных от устройства через USB ISO, компилятор tdm64. Скачиваете libusbK-dev-kit и заменяете файлы на те, что из архива: libusbK_dev_kit.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться