Перейти к содержанию
    

Left Radio

Участник
  • Постов

    48
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о Left Radio

  • Звание
    Участник
    Участник
  • День рождения 25.03.1984
  1. Прерывания по приходу данных блокируется после IINCOMPISOOUT, о чем написано в RM0090, а в качестве одной из причин возникновения IINCOMPISOOUT указывается медлительность вычитки RxFIFO, также указывается на возможно неправильный заголовок или CRC пакета, причем нигде нет указаний как определить источник проблемы. Как я написал ранее, проблема скорее всего не в вычитке так так данных по EP OUT с хоста нет а прерывание IINCOMPISOOUT все равно вызывается одно за одним как только активирую любую изохронную EP OUT. Еще раз замечу что в bulk никаких проблем не возникает вообще, ни с вычиткой FIFO, ни со всем остальным, поэтому и начинаю думать о поддержке ядром HS STM изохронных передач именно в HS, в FS так же как и с bulk все отлично работает. Прерывания SOF/EOPF идут микрофреймами, проверил просто счетчиком в SOF с переключением IO и замеряя получившуюся частоту осциллом. Кстати RxFIFO в STM32F4 общее для всех EP.
  2. Вижу я тут сам себе пейсатель :laughing: :), ну да ладно разбираюсь дальше, как определить все ли приняли по EOPF разобрался, элементарно отслеживать xfer_cnt, но мне это бестолку причина как мне становится ясным не в том, предположения сейчас два, первое - ошибки заголовка пакетов/самих пакетов данных, второе - у ядра HS USB STM нет нативной аппаратной поддержки HS Isochronous EP и возможно ли эту проблему обойти неясно. USBLyzer, BusHound никаких ошибок или аномального поведения не позволяют выявить, а аппаратного инструментария для мониторинга USB нет, как и нет лог. анализатора на 60МГц :(. Осциллограф на 100МГц есть, но в данном случае не очень помогает, разве что посмотрел форму сигналов ULPI, там вроде бы все нормально. Отписался на офф. форуме ST, но пока тишина и там, начинаю подумывать над своими драйверами и тогда можно перейти на bulk вместо isochronous, но блин не очень хочется углубятся в это все, да и уйму времени займет :(.
  3. Пока остается заключить что HS ядро USB в STM32F4 не может корректно работать с isochronous EP. Прочитал статусные регистры GREGS.OTG_HS_GRXSTSR/GREGS.OTG_HS_GRXSTSP по прерыванию IINCOMPISOOUT, судя из прочитанных значений я получаю пакеты с CHNUM - 0000, BCNT - 0x08, PID - 00, PKTSTS - 0110, но это больше похоже на setup пакет по нулевой EP чем на пакеты данных по EP1, возможно это старые значения с setup пакета ведь данных по EP1 также пока не должно быть так как с хоста данные не идут (как же тогда вообще блин возникает IINCOMPISOOUT??? :cranky:). Перепроверил когда начинаю получать прерывания IINCOMPISOOUT - сразу как только активирую любую по номеру изохронную конечную точку OUT, после енумерации и конфигурации устройства естественно. Кстати прерываний Isochronous out packet dropped у меня нет. Порывшись еще в гугле так и не нашел ни одного примера работы с изохронными точками в HS на STM :(, надеялся что возможно в новой библиотеке stm32cubef4, но нет, причем пример для аудио там есть только для FS и HS_IN_FS, все это подпитывает мой пессимизм по возможности запуска HS USB Audio на STM32F4 :(. А пока продолжая читать usb_20.pdf :) увидел в таблице Table 8-1. PID Types два интересных значения PID для пакетов : DATA2 0b001 Data packet PID high-speed, high bandwidth isochronous transaction in a microframe (see Section 5.9.2 for more information) MDATA 0b001 Data packet PID high-speed for split and high bandwidth isochronous transactions (see Sections 5.9.2, 11.20, and 11.21 for more information) Но в документации и библиотеке от STM нет ни слова про эти значения PID, в Endpoint controls на стр. 1073 есть только: ● Program the expected or transmitted data0/data1 PID (bulk/interrupt only) ● Program the even/odd frame during which the transaction is received or transmitted(isochronous only) Еще в 30.7.2 Peripheral SOFs указано: The end of periodic frame interrupt (GINTSTS/EOPF) is used to notify the application when 80%, 85%, 90% or 95% of the time frame interval elapsed depending on the periodic frame interval field in the device configuration register (PFIVL bit in OTG_HS_DCFG). This feature can be used to determine if all of the isochronous traffic for that frame is complete. Но к сожалению не указано как именно можно determine :(
  4. Interrupt тут не причем я жду прерывания по готовности данных в приемном FIFO, вот часть рекомендуемой последовательности в RM0090(стр. 1205): 3. In Slave mode, wait for the RXFLVL interrupt (in OTG_HS_GINTSTS) and empty the data packets from the receive FIFO – This step can be repeated many times, depending on the transfer size. 4. The assertion of the XFRC interrupt (in OTG_HS_DOEPINTx) marks the completion of the isochronous OUT data transfer. This interrupt does not necessarily mean that the data in memory are good. Таймер запустить и синхронизировать с SOF не проблема, но зачем, надо будет к тому же ждать пока весь кадр ляжет в FIFO, да и ведь уже есть прерывания SOF/EOPF, можно забирать данные по тому же принципу по SOF, или в крайнем случае по EOPF, хотя последнее противоречит доке. Да и это не работает, такое впечатление что что то не так с самим Iso OUT EP в HS или проблема с организацией самой изохронной передачи в HS core, но это только впечатление. Возможно также я не правильно читаю FIFO, но тут тоже не до конца понятно, в FS где тот же проект(естественно сконфигурированный под FS) работает правильно , и когда приходит прерывание XFRC данные уже лежат в буфере который я указал при инициализации EP(эти функции собственно часть библиотеки STM): uint8_t usbd_audio_Init (void *pdev, uint8_t cfgidx) { /* Open EP OUT */ DCD_EP_Open((USB_OTG_CORE_HANDLE*)&USB_OTG_dev, AUDIO_OUT_EP, AUDIO_OUT_PACKET, USB_OTG_EP_ISOC); /* Initialize the Audio output Hardware layer */ if (AUDIO_OUT_fops.Init(AUDIO_FREQUENCY, DEFAULT_VOLUME, 0) != USBD_OK) { return USBD_FAIL; } /* Prepare Out endpoint to receive audio data */ DCD_EP_PrepareRx((USB_OTG_CORE_HANDLE*)&USB_OTG_dev, AUDIO_OUT_EP, (uint8_t*)IsocOutWrPtr, AUDIO_OUT_PACKET); return USBD_OK; } uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev , uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type) { USB_OTG_EP *ep; if ((ep_addr & 0x80) == 0x80) { ep = &pdev->dev.in_ep[ep_addr & 0x7F]; } else { ep = &pdev->dev.out_ep[ep_addr & 0x7F]; } ep->num = ep_addr & 0x7F; ep->is_in = (0x80 & ep_addr) != 0; ep->maxpacket = ep_mps; ep->type = ep_type; if (ep->is_in) { /* Assign a Tx FIFO */ ep->tx_fifo_num = ep->num; } /* Set initial data PID. */ if (ep_type == USB_OTG_EP_BULK ) { ep->data_pid_start = 0; } USB_OTG_EPActivate(pdev , ep ); return 0; } uint32_t DCD_EP_PrepareRx( USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len) { USB_OTG_EP *ep; ep = &pdev->dev.out_ep[ep_addr & 0x7F]; /*setup and start the Xfer */ ep->xfer_buff = pbuf; ep->xfer_len = buf_len; ep->xfer_count = 0; ep->is_in = 0; ep->num = ep_addr & 0x7F; if (pdev->cfg.dma_enable == 1) { ep->dma_addr = (uint32_t)pbuf; } if ( ep->num == 0 ) { USB_OTG_EP0StartXfer(pdev , ep); } else { USB_OTG_EPStartXfer(pdev, ep ); } return 0; } USB_OTG_STS USB_OTG_EPActivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) { USB_OTG_STS status = USB_OTG_OK; USB_OTG_DEPCTL_TypeDef depctl; USB_OTG_DAINT_TypeDef daintmsk; __IO uint32_t *addr; depctl.d32 = 0; daintmsk.d32 = 0; /* Read DEPCTLn register */ if (ep->is_in == 1) { addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL; daintmsk.ep.in = 1 << ep->num; } else { addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL; daintmsk.ep.out = 1 << ep->num; } /* If the EP is already active don't change the EP Control * register. */ depctl.d32 = USB_OTG_READ_REG32(addr); if (!depctl.b.usbactep) { depctl.b.mps = ep->maxpacket; depctl.b.eptype = ep->type; depctl.b.txfnum = ep->tx_fifo_num; depctl.b.setd0pid = 1; depctl.b.usbactep = 1; USB_OTG_WRITE_REG32(addr, depctl.d32); } /* Enable the Interrupt for this EP */ #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID)) { USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, 0, daintmsk.d32); } else #endif USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, 0, daintmsk.d32); return status; } USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) { USB_OTG_STS status = USB_OTG_OK; USB_OTG_DEPCTL_TypeDef depctl; USB_OTG_DEPXFRSIZ_TypeDef deptsiz; USB_OTG_DSTS_TypeDef dsts; uint32_t fifoemptymsk = 0; depctl.d32 = 0; deptsiz.d32 = 0; /* IN endpoint */ if (ep->is_in == 1) { depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPCTL)); deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ)); /* Zero Length Packet? */ if (ep->xfer_len == 0) { deptsiz.b.xfersize = 0; deptsiz.b.pktcnt = 1; } else { /* Program the transfer size and packet count * as follows: xfersize = N * maxpacket + * short_packet pktcnt = N + (short_packet * exist ? 1 : 0) */ deptsiz.b.xfersize = ep->xfer_len; deptsiz.b.pktcnt = (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket; if (ep->type == EP_TYPE_ISOC) { deptsiz.b.mc = 1; } } USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ, deptsiz.d32); if (pdev->cfg.dma_enable == 1) { USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr); } else { if (ep->type != EP_TYPE_ISOC) { /* Enable the Tx FIFO Empty Interrupt for this EP */ if (ep->xfer_len > 0) { fifoemptymsk = 1 << ep->num; USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk); } } } if (ep->type == EP_TYPE_ISOC) { dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); if (((dsts.b.soffn)&0x1) == 0) { depctl.b.setd1pid = 1; } else { depctl.b.setd0pid = 1; } } /* EP enable, IN data in FIFO */ depctl.b.cnak = 1; depctl.b.epena = 1; USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPCTL, depctl.d32); if (ep->type == EP_TYPE_ISOC) { USB_OTG_WritePacket(pdev, ep->xfer_buff, ep->num, ep->xfer_len); } } else { /* OUT endpoint */ depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL)); deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ)); /* Program the transfer size and packet count as follows: * pktcnt = N * xfersize = N * maxpacket */ if (ep->xfer_len == 0) { deptsiz.b.xfersize = ep->maxpacket; deptsiz.b.pktcnt = 1; } else { deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket; deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket; } USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32); if (pdev->cfg.dma_enable == 1) { USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr); } if (ep->type == EP_TYPE_ISOC) { if (ep->even_odd_frame) { depctl.b.setd1pid = 1; } else { depctl.b.setd0pid = 1; } } /* EP enable */ depctl.b.cnak = 1; depctl.b.epena = 1; USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL, depctl.d32); } return status; } А значит вычитка FIFO произошла до прерывания XFRC, скорее всего по прерываниям RXFLVL как и рекомендовано в доке. И все это прекрасно работает в FS режиме, а после переконфигурации на HS ядро, внешний PHY, и правки дескрипторов, начинаются вот такие чудеса с прерываниями IINCOMPISOOUT и как следствие блокированием прерываний RXFLVL и XFRC :( , возможно есть какие либо особенности при работе isochronous в HS по сравнению с FS не знаю, пока ничего такого не нашел. Но это все может оказаться бесполезным, так как не ясен источник IINCOMPISOOUT, если это искажение данных пакетов и/или неверный CRC, то как бы не читать будет явно не нормально :(, как выяснить источник этого прерывания так и остается неясным. Как вариант можно заподозрить и аппаратную часть если бы не нормальная работа в VCP HS режиме, о чем писал раньше, наигрался я с этим примером достаточно, начинаются проблемы только когда сбиваю кварц МК или кварц USB3300 :).
  5. Продолжаю затирать до дыр RM0090, в главе Generic isochronous OUT data transfer(стр. 1204) описана общая схема, у меня все полностью соответствует этой схеме, значения регистров OTG_HS_GINTSTS, OTG_HS_DOEPCTLx, OTG_HS_DSTS также нормальны, единственное что это не совсем понятен механизм: 3. The application must read all isochronous OUT data packets from the receive FIFO(data and status) before the end of the periodic frame (EOPF interrupt in OTG_HS_GINTSTS). Как я понимаю выполнить это требование можно только получая прерывание готовности данных по приему OTG_HS_DOEPINTx.XFRC или по RXFLVL(как я понял только при вкл. DMA?), но эти прерывания почему то не приходят по OUT EP данных. Если же попытаться использовать прерывания SOF или EOPF то уже не получится вычитать данные так как требует документация, по EOPF можно только подготовить EP к приему и насколько понял правильно это будет делать каждый восьмой микрофрейм для EP c bInterval - 1мс (0x04 в дескрипторе EP), так ли это? Попробовал так сделать, данные начали приходить и приходят все пакеты, но с ошибками, а почему опять неясно, либо я вообще все делаю неправильно, либо другие аппаратные/программные проблемы. По аппаратным я сомневаюсь, плата разведена более-менее правильно и соблюдены рекомендации по USB3300, линии данных/клок максимум 30-40мм, питание чистое, да и VCP, как уже писал, работает просто отлично. Далее из возможных причин возникновения INCOMPISOOUT указываются: – When the receive FIFO cannot accommodate the complete ISO OUT data packet, the core drops the received ISO OUT data – When the isochronous OUT data packet is received with CRC errors – When the isochronous OUT token received by the core is corrupted – When the application is very slow in reading the data from the receive FIFO как определить что именно из этого списка произошло намеков нет :(, сам до причин докопаться пока не смог, INCOMPISOOUT вызывается похоже каждый микрофрейм даже когда хост не шлет данные в EP1, а сразу после инициализации и установки altsettings0. Уверен правда что не первый пункт так как выделяю для FIFO больше размера одного пакета(192 байт), на всякий случай попробовал разные значения в разумных пределах, но как и ожидал ничего не поменялось. P.S. Возможно у кого нибудь есть любой рабочий проект для обмена с использованием isochronous EP, необязательно аудио, в HS под STM? Был бы признателен за любой пример.
  6. Покопавшись еще, пусть наверно кривовато :blink: , но заставил таки принимать данные, включил прерывание eopframe и в процессе опытов поставил в обработчике: if (gintr_status.b.eopframe) { ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[AUDIO_OUT_EP].even_odd_frame = (((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[AUDIO_OUT_EP].even_odd_frame)? 0:1; DCD_EP_PrepareRx(pdev, AUDIO_OUT_EP, (uint8_t*)(IsocOutBuff), AUDIO_OUT_PACKET_SZE); } Incomplete isochronous OUT прекратились, данные вроде бы идут нормально(корректность данных еще не проверял), но насколько это правильно? Может кто нибудь подсказать как тут будет правильней сделать и что я возможно делаю не так? Дайте плиз хоть направление куда смотреть, а то уже начинаю запутываться окончательно :(
  7. Нет не по таймеру, разрешены прерывания по приему OUT EP1, но вот они никогда не приходят для любых EP(переназначал EP1 на EP2-4) отличных от нулевого. Возможно ли что в HS у STM32F4 с OUT прерыванием в изохронном режиме проблемы? В errata sheet правда я ничего по этому поводу не увидел :(. Может и правда нужно самому опрашивать, но насколько это будет корректно? А если конечных точек не одна, как у меня сейчас, а много? Поставил в цикле проверять статус EP1, получаю всегда USB_OTG_EP_RX_VALID (0x3000), можно пример как в тупую, в цикле, опрfашивать EP OUT и вычитать из FIFO данные если чего то принято?
  8. Да не очень пока продвигается :(, протестировал на скорость в bulk, делал на примере VCP и получил скорость ~30Mbit/sec Loopback-ом, вполне достаточно для потока какой я хочу пропихнуть в изохронном режиме в аудио, но по прежнему не могу разобраться что есть источник бесконечных Incomplete isochronous OUT :(, как узнать причину их возникновения, возможно я не те регистры смотрю?. Есть мысль что у меня не вычитываются FIFO при приеме, но как я их могу вычитать если прерывания по приему вообще не приходят по конечной точке данных ( EP1 ) :smile3046: Вот дескрипторы сразу для UAC1/UAC2, описанная выше проблема возникает в обоих режимах. #ifdef USE_AUDIO_CLASS_01_00 /* USB Standard Device Descriptor */ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[uSB_SIZ_DEVICE_DESC] __ALIGN_END = { 0x12, /*bLength */ USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/ 0x00, /*bcdUSB */ 0x02, USB_DEVICE_CLASS_AUDIO, /*bDeviceClass*/ 0x00, /*bDeviceSubClass*/ 0x00, /*bDeviceProtocol*/ USB_OTG_MAX_EP0_SIZE, /*bMaxPacketSize*/ LOBYTE(USBD_VID), /*idVendor*/ HIBYTE(USBD_VID), /*idVendor*/ LOBYTE(USBD_PID), /*idVendor*/ HIBYTE(USBD_PID), /*idVendor*/ 0x00, /*bcdDevice rel. 2.00*/ 0x02, USBD_IDX_MFC_STR, /*Index of manufacturer string*/ USBD_IDX_PRODUCT_STR, /*Index of product string*/ USBD_IDX_SERIAL_STR, /*Index of serial number string*/ USBD_CFG_MAX_NUM /*bNumConfigurations*/ } ; /* USB_DeviceDescriptor */ /* USB Standard Device Descriptor */ uint8_t USBD_DeviceQualifierDesc[uSB_LEN_DEV_QUALIFIER_DESC] = { USB_LEN_DEV_QUALIFIER_DESC, USB_DESC_TYPE_DEVICE_QUALIFIER, 0x00, 0x02, 0x00, 0x00, 0x00, USB_OTG_MAX_EP0_SIZE, 0x01, 0x00, }; #else /* USB Standard UAC2 Device Descriptor */ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[uSB_SIZ_DEVICE_DESC] __ALIGN_END = { USB_SIZ_DEVICE_DESC, /*bLength */ USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/ 0x00, /*bcdUSB 0x0200 */ 0x02, 0xEF, /*bDeviceClass*/ 0x02, /*bDeviceSubClass*/ 0x01, /*bDeviceProtocol*/ USB_OTG_MAX_EP0_SIZE, /*bMaxPacketSize*/ LOBYTE(USBD_VID), /*idVendor*/ HIBYTE(USBD_VID), /*idVendor*/ LOBYTE(USBD_PID), /*idVendor*/ HIBYTE(USBD_PID), /*idVendor*/ 0x00, /*bcdDevice rel. 2.00*/ 0x02, USBD_IDX_MFC_STR, /*Index of manufacturer string*/ USBD_IDX_PRODUCT_STR, /*Index of product string*/ USBD_IDX_SERIAL_STR, /*Index of serial number string*/ USBD_CFG_MAX_NUM /*bNumConfigurations*/ }; /* USB_DeviceDescriptor */ /* USB Standard UAC2 Device Descriptor */ __ALIGN_BEGIN uint8_t USBD_DeviceQualifierDesc[uSB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { USB_LEN_DEV_QUALIFIER_DESC, USB_DESC_TYPE_DEVICE_QUALIFIER, 0x00, 0x02, 0xEF, 0x02, 0x01, USB_OTG_MAX_EP0_SIZE, 0x01, 0x00, }; #endif #ifdef USE_AUDIO_CLASS_01_00 /* USB AUDIO device Configuration Descriptor */ __ALIGN_BEGIN uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE] __ALIGN_END = { /* Configuration 1 */ 0x09, /* bLength */ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ LOBYTE(AUDIO_CONFIG_DESC_SIZE), /* wTotalLength */ HIBYTE(AUDIO_CONFIG_DESC_SIZE), 0x02, /* bNumInterfaces */ 0x01, /* bConfigurationValue */ 0x00, /* iConfiguration */ 0xC0, /* bmAttributes BUS Powred */ 0x0A, /* bMaxPower */ /* 09 byte*/ /* USB Speaker Standard interface descriptor */ AUDIO_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x00, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x00, /* bNumEndpoints */ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ 0x00, /* iInterface */ /* 09 byte*/ /* USB Speaker Class-specific AC Interface Descriptor */ AUDIO_INTERFACE_DESC_SIZE, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */ 0x00, /* 1.00 */ /* bcdADC */ 0x01, LOBYTE(0x27), /* wTotalLength = 39*/ HIBYTE(0x27), 0x01, /* bInCollection */ 0x01, /* baInterfaceNr */ /* 09 byte*/ /* USB Speaker Input Terminal Descriptor */ AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */ AUDIO_INPUT_TERMINAL_ID, /* bTerminalID */ 0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */ 0x01, 0x00, /* bAssocTerminal */ AUDIO_CHANNELS_COUNT, /* bNrChannels */ LOBYTE(AUDIO_CHANNELS_INPUT_TERMINAL_SETTINGS), /* wChannelConfig 0x0001 - LF, 0x0002 - RF, 0x0004 - CF, 0x0008 - LFE */ HIBYTE(AUDIO_CHANNELS_INPUT_TERMINAL_SETTINGS), 0x00, /* iChannelNames */ 0x00, /* iTerminal */ /* 12 byte*/ /* USB Speaker Audio Feature Unit Descriptor */ 0x09, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */ AUDIO_FEATURE_UNIT_TERMINAL_ID, /* bUnitID */ AUDIO_INPUT_TERMINAL_ID, /* bSourceID */ 0x01, /* bControlSize */ 0x01, /* bmaControls(0) MUTE */ 0x00, /* bmaControls(1) */ 0x00, /* iTerminal */ /* 09 byte*/ /*USB Speaker Output Terminal Descriptor */ 0x09, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */ AUDIO_OUTPUT_TERMINAL_ID, /* bTerminalID */ 0x05, /* wTerminalType 0x0301 - headphone, 0x0602 - Digital Interface, 0x0305 - Room speaker*/ 0x03, 0x00, /* bAssocTerminal */ AUDIO_FEATURE_UNIT_TERMINAL_ID, /* bSourceID */ 0x00, /* iTerminal */ /* 09 byte*/ /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */ /* Interface 1, Alternate Setting 0 */ AUDIO_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x01, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x00, /* bNumEndpoints */ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ 0x00, /* iInterface */ /* 09 byte*/ /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */ /* Interface 1, Alternate Setting 1 */ AUDIO_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x01, /* bInterfaceNumber */ 0x01, /* bAlternateSetting */ 0x01, /* bNumEndpoints */ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ 0x00, /* iInterface */ /* 09 byte*/ /* Class-specific Audio Streaming Interface Descriptor */ AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ AUDIO_INPUT_TERMINAL_ID, /* bTerminalLink */ 0x00, /* bDelay */ 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/ 0x00, /* 07 byte*/ /* USB Speaker Audio Type I Format Interface Descriptor */ 0x0B, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ AUDIO_FORMAT_TYPE_I, /* bFormatType */ AUDIO_CHANNELS_COUNT, /* bNrChannels */ AUDIO_FRAME_SIZE, /* bSubFrameSize */ AUDIO_BITRESOLUTION, /* bBitResolution*/ 0x01, /* bSamFreqType only one frequency supported */ SAMPLE_FREQ, /* Audio sampling frequency coded on 3 bytes */ /* 11 byte*/ /* Endpoint 1 - Standard Descriptor */ AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/ USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes, isochronus, async */ LOBYTE((uint16_t)AUDIO_OUT_PACKET), HIBYTE((uint16_t)AUDIO_OUT_PACKET), 0x04, /* bInterval */ 0x00, /* bRefresh */ 0x00, /* bSynchAddress */ /* 09 byte*/ /* Endpoint - Audio Streaming Descriptor*/ AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */ AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ 0x00, /* bmAttributes */ 0x00, /* bLockDelayUnits */ 0x00, /* wLockDelay */ 0x00, /* 07 byte*/ }; #endif #ifdef USE_AUDIO_CLASS_02_00 /* USB AUDIO UAC2 device Configuration Descriptor */ static volatile uint8_t usbd_audio_CfgDesc[uSB_AUDIO_DESC_SIZ] = { /* Configuration 1 */ 0x09, /* bLength */ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ LOBYTE(AUDIO_CONFIG_DESC_SIZE), /* wTotalLength */ HIBYTE(AUDIO_CONFIG_DESC_SIZE), 0x02, /* bNumInterfaces */ 0x01, /* bConfigurationValue */ 0x00, /* iConfiguration */ 0xC0, /* bmAttributes BUS Powred*/ 250, /* bMaxPower = 100 mA*/ /* 09 byte*/ /* --- UAC2 configuration description, see page 46 in * "Universal Serial Bus Device Class Definition for Audio Devices" (Audio20 final.pdf) --- */ /* Standard IAD Interface Descriptor */ 8, /* bLength */ AUDIO_IAD_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x00, /* bFirstInterface */ 0x02, /* bInterfaceNumber */ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass AUDIO */ 0x00, /* bInterfaceSubClass UNDEFINED */ AUDIO_PROTOCOL_IP_VERSION_02_00, /* bInterfaceProtocol */ 0x00, /* iInterface */ /* 08 byte*/ /* Standard AC(AudioControl) Interface Descriptor */ AUDIO_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x00, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x00, /* bNumEndpoints */ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */ AUDIO_PROTOCOL_IP_VERSION_02_00, /* bInterfaceProtocol */ 0x00, /* iInterface */ /* 09 byte*/ /* Class-specific AC(AudioControl) Interface Descriptor */ AUDIO_INTERFACE_DESC_SIZE, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */ 0x00, 0x02, /* bcdADC 2.00 */ 0x01, /* bCategory */ LOBYTE(0x003C), /* wTotalLength Total number of bytes returned for the class-specific */ HIBYTE(0x003C), /* AudioControl interface descriptor. Includes the combined length */ /* of this descriptor header and all Clock Source, Unit and Terminal descriptors.*/ 0x00, /* bmControls */ /* 09 byte*/ /* Standart CSD(Clock Sourse) 44.1k Interface Descriptor */ 8, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_CONTROL_CLOCK_SOURSE, /* bDescriptorSubtype */ 0x10, /* bClockID */ 0x01, /* bmAttributes, 0x01 - Internal fixed Clock */ 0x07, /* bmControls, 0b00000111 - freq r/w, validity r */ 0x00, /* bAssocTerminal */ 0x00, /* iClockSource */ /* 08 byte*/ /* Audio Input Terminal Descriptor */ 0x11, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */ 0x20, /* bTerminalID */ 0x01, 0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */ 0x00, /* bAssocTerminal */ 0x10, /* bCSourceID - CSD/CXD ID */ 0x01, /* bNrChannels */ 0x00, 0x00, 0x00, 0x00, /* bmChannelConfig 0x00000003 - Left&Right; 0x0000 - Mono; 0x0004 - FrontCenter */ 0x00, /* iChannelNames */ 0x00, 0x00, /* bmControls */ 0x00, /* iTerminal */ /* 17 byte*/ /* USB Speaker Audio Feature Unit Descriptor */ 0x0E, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */ 0x30, /* bUnitID */ 0x20, /* bSourceID */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* iTerminal */ /* 6 + ((ch + 1) * 4) byte */ /* USB Speaker Output Terminal Descriptor */ 0x0C, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */ 0x40, /* bTerminalID */ 0x01, /* wTerminalType 0x0301, headphones*/ 0x03, 0x00, /* bAssocTerminal */ 0x30, /* bSourceID */ 0x10, /* bCSourceID - CXD ID */ 0x00, 0x00, /* bmControls */ 0x00, /* iTerminal */ /* 12 byte*/ /* Standard AS Interface Descriptor - Audio Streaming Zero Bandwith Interface 1, Alternate Setting 0 */ AUDIO_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x01, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x00, /* bNumEndpoints */ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ AUDIO_PROTOCOL_IP_VERSION_02_00, /* bInterfaceProtocol */ 0x00, /* iInterface */ /* 09 byte*/ /* Standard AS Interface Descriptor - Audio Streaming Interface 1, Alternate Setting 1 */ AUDIO_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x01, /* bInterfaceNumber */ 0x01, /* bAlternateSetting */ 0x01, /* bNumEndpoints */ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ AUDIO_PROTOCOL_IP_VERSION_02_00, /* bInterfaceProtocol */ 0x00, /* iInterface */ /* 09 byte*/ /* Class-specific AS Interface Descriptor */ 0x10, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ 0x20, /* bTerminalLink - Input Terminal */ 0x00, /* active alt settings r/w, valid alt settings r */ AUDIO_FORMAT_TYPE_I, /* bFormatType */ 0x01, 0x00, 0x00, 0x00, /* bFormatTag - AUDIO_FORMAT_PCM 0x0001*/ 0x01, /* bNrChannels */ 0x00, 0x00, 0x00, 0x00, /* L+R front */ 0x00, /* iChannelNames */ /* 16 byte*/ /* USB Speaker Audio Type I Format Interface Descriptor */ 0x06, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ AUDIO_FORMAT_TYPE_I, /* bFormatType */ 0x02, /* bSubFrameSize; bytes per frame */ 0x18, /* bBitResolution; bits per sample */ /* 06 byte*/ /* Endpoint 1 - Standard Descriptor */ 0x07, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/ 0x01, /* bmAttributes, isochronus, async, explict fb */ 0xC0, 0x00, /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */ 0x04, /* bInterval */ /* 07 byte*/ /* Endpoint - Audio Streaming Descriptor*/ 0x08, /* bLength */ AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ 0x00, /* bmAttributes, default 0x00 */ 0x01, /* bmControls, default 0x00 */ 0x01, /* bLockDelayUnits */ 0x01, 0x00, /* wLockDelay */ /* 08 byte*/ }; #endif
  9. Всем доброго времени! Прошу подскажите куда копать уже несколько дней и бессонных ночей :) никак не поедут лыжи :( В общем пытаюсь запустить аудио поток по HS USB используя PHY USB3300 и STM32F407VE на своей плате, устройство определяется правильно, драйвера устанавливаются для UAC1 в Win7, и нормально видится в linux в UAC1 и UAC2, но как только устройство правильно приконектилось и пошли SOF-ы начинает вызваться прерывание Incomplete isochronous OUT (INCOMPISOOUT в регистре OTG_HS_GINTSTS), причем получаю их постоянно, одно за другим, данные по EP1 естественно при этом не идут, а по EP0 обмен с компом идет нормально (иначе бы ОС не увидело бы девайса, да и перепроверил). Я использую OTG драйвер от ST и там в обработчике DCD_IsoOUTIncomplete_ISR только сбрасывается прерывание и все, что явно в противоречии с процедурой описанной в доке (Incomplete isochronous OUT data transfers, стр. 1205), пробовал сделать обработку прерывания как там написано, но толку с этого ноль :( Никак не могу понять почему происходит потеря пакетов, код рабочий, с встроенным FS PHY все работает отлично на другой плате(естественно с реконфигурацией проекта под FS). Железо скорее всего ни причем, так как идет нормальный обмен по EP0, корректно обрабатываются запросы на дескрипторы и на установку AltSettings 0/1. В качестве проверки запускал VCP HS на устройстве с тем же драйвером OTG от ST, правда там bulk а не isochronous, но главное что работает и работает стабильно. Дескрипторы если нужно выложу, но мне кажется скорее всего проблема не там, и еще подскажите пожалуйста по встроенному DMA под USB HS, как его настроить и куда оно будет ложить данные? Про выравнивание при его использовании знаю, в лоб включение DMA ничего не решает, все также девайс определяется правильно но и по прежнему теряются пакеты :( Буду рад за любую подсказку, спасибо!
  10. Хм..., у меня абсолютно такой же алгоритм, разве что буфер общий и поэтому расстояние удерживается в половину буфера, ладно буду разбираться, спасибо еще раз.
  11. Спасибо, поизучаю, а буфер там циклический, точно так же по DMA отправляется в I2S?
  12. Проясните каким образом хост увеличивает количество байт в посылке? Дело в том что при воспроизведении время от времени проскакивают слабозаметные щелчки, скорость выдачи байт я засинхронизировал, тут проблем нет, думаю не может быть причина в том, что теперь ведь посылки с хоста не равны 384 байт (это для 16/96), а при заполнении буфера, если посылка например 388 байт и она не умещается в конец буфера, то я ее режу на две, одну часть в конец, все что не влезло в начало. Разрезается естественно только по 2 байта(16), но может ли хост выдать нечетное количество байт, из-за чего и появляются щелчки? Буфер читает DMA по кругу.
  13. А вот это интересно, хорошо что в STM так можно, собственно сейчас у меня у IN и OUT один номер, значит можно будет надеяться прикрутить драйвера других карт, и работать в обеих направлениях B). 512 байт конечно печально, а я то думаю почему только 48 для UAC1, когда в исходниках лазил. По поводу HS PHY, прикручу USB3320, когда конечно нет предпочтений возможно действительно проще, всё равно ведь изучать, так лучше уж то что больше подходит :), а мне проще внешний прикрутить чем переходить сейчас на LPC. Единственный пока недостаток - невозможность работы с форматом 24 BCK на фрейм, только 16/32, правда не знаю умеет ли это LPC, но при большой необходимости можно завести данные в ПЛИС, а там уже получить любой формат не проблема. Плюс ПЛИС даст еще кучу всяких возможностей, например соединиться по параллельной шине и получить сколько нужно I2S выходов а не только 2. Но это если и буду делать, то не сейчас, хотя EPM570 уже прикупил :).
  14. Хороший проект, респект ;), а какие ограничения avr32 неустроили? LPC18**/LPC43** неплохие машинки, тоже смотрел в их сторону, но потом решил в пользу STM32F407, так как знаю их лучше, а с LPC никогда не работал. Пока устраивает полностью, жаль конечно нет HS PHY. Сейчас довожу до ума работу с UAC 1 и доделываю управление для Si5351. Можно сказать в самом начале :)
  15. Да, UAC 1, за UAC 2 пока не берусь, доведу полностью до ума и хочу перейти на HS(USB3320), затем возможно за UAC 2 возмусь. Правда драйвера никогда не писал, поэтому вероятно на основе sdr-widget.
×
×
  • Создать...