|
STM32F2xx USB FS ISO IN EP libusb, Как работать в libusb с изохронными EP? |
|
|
|
May 5 2013, 16:25
|
Частый гость
 
Группа: Участник
Сообщений: 144
Регистрация: 28-08-07
Пользователь №: 30 111

|
Никак не могу понять, как работать с изохронными конечными точками в 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.pdfCODE /* 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 конечную точку. Сделал пробную непрерывную передачу буфера на ПК: CODE #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; }
В итоге, устройство нормально определяется, присоединяюсь к конечной точке, данные приходят. Но вот только приходят они каким-то непонятным образом. Программа на ПК: CODE #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 особо никакой нет. Может кто уже реализовывал подобное, куда копать?
Сообщение отредактировал BaN - May 5 2013, 16:28
Эскизы прикрепленных изображений
Прикрепленные файлы
log.txt ( 1.35 мегабайт )
Кол-во скачиваний: 72
|
|
|
|
|
 |
Ответов
(1 - 5)
|
May 6 2013, 05:30
|
Местный
  
Группа: Свой
Сообщений: 217
Регистрация: 1-02-05
Пользователь №: 2 332

|
Цитата(BaN @ May 5 2013, 23:25)  Никак не могу понять, как работать с изохронными конечными точками в libusb-win32-1.2.6.0. Видимо, я что-то не так делаю при работе с libusb, но так и не могу понять как правильно, документации на libusb особо никакой нет. Может кто уже реализовывал подобное, куда копать? Я делал нечто похожее правда для HS и на libusbk, но начинал для FS и на libusb. Сейчас не помню из-за каких конкретно проблем с изохронными передачами в libusb перешел на libusbk, но с последней работа пошла гораздо бодрее. Да, кстати, а зачем использовать libusb для обычного USB Audio? Чем стандартный Win драйвер не угодил?
|
|
|
|
|
May 6 2013, 07:40
|
Частый гость
 
Группа: Участник
Сообщений: 144
Регистрация: 28-08-07
Пользователь №: 30 111

|
Цитата(nikkov @ May 6 2013, 12:30)  Я делал нечто похожее правда для HS и на libusbk, но начинал для FS и на libusb. Сейчас не помню из-за каких конкретно проблем с изохронными передачами в libusb перешел на libusbk, но с последней работа пошла гораздо бодрее. Да, кстати, а зачем использовать libusb для обычного USB Audio? Чем стандартный Win драйвер не угодил? Хм, что-то я об очевидном не подумал, попробую использовать его.
|
|
|
|
|
May 7 2013, 05:15
|
Частый гость
 
Группа: Участник
Сообщений: 144
Регистрация: 28-08-07
Пользователь №: 30 111

|
Сделал передачу от устройства потока 16-бит 48кГц 1 канал с дескриптором: CODE #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
Сообщение отредактировал BaN - May 7 2013, 06:25
|
|
|
|
|
Oct 14 2014, 18:32
|
Группа: Новичок
Сообщений: 2
Регистрация: 9-03-14
Пользователь №: 80 863

|
Я тоже пытаюсь запустить аудио на stm32f205. BaN, можете выложить свои исходники?
|
|
|
|
|
Oct 19 2014, 09:48
|
Частый гость
 
Группа: Участник
Сообщений: 144
Регистрация: 28-08-07
Пользователь №: 30 111

|
Проект Eclipse+gcc с USB ISO:
IKAIS_ADC.rar ( 555.27 килобайт )
Кол-во скачиваний: 213Программа под Windows для приема данных от устройства через USB ISO, компилятор tdm64. Скачиваете libusbK-dev-kit и заменяете файлы на те, что из архива:
libusbK_dev_kit.rar ( 32.97 килобайт )
Кол-во скачиваний: 171
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|