реклама на сайте
подробности

 
 
> STM32F2xx USB FS ISO IN EP libusb, Как работать в libusb с изохронными EP?
BaN
сообщение May 5 2013, 16:25
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 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.pdf
CODE
/* 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
 
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 20:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01369 секунд с 7
ELECTRONIX ©2004-2016