Я эту ситуацию ловил как результат порчи FIFO из-за взаимного перекрытия областей разных ендпоинтов.
Не совсем как в документации инициализирую GRXFSIZ - если точно по формуле, висим. Попробуйте увеличить, не забывая про размер FIFO (для FS - 1280 байт).
to Шаманъ: а попробовать мой исходник затащить? На каждом углу же предлагаю взять...
static uint32_t usbd_makefifoparam(uint_fast16_t base, uint_fast16_t size)
{
return ((uint32_t) size << 16) | base;
}
// Преобразование размера в байтах размера данных в требования к fifo
// Расчет аргумента функции HAL_PCDEx_SetRxFiFo, HAL_PCDEx_SetTxFiFo
static uint_fast16_t size2buff4(uint_fast16_t size)
{
const uint_fast16_t size4 = (size + 3) / 4; // размер в 32-бит значениях
return ulmax16(0x10, size4);
}
static void usbd_fifo_initialize(PCD_HandleTypeDef * hpcd, uint_fast16_t fullsize)
{
PCD_TypeDef * const instance = hpcd->Instance;
// DocID028270 Rev 2 (RM0410): 41.11.3 FIFO RAM allocation
// DocID028270 Rev 2 (RM0410): 41.16.6 Device programming model
uint_fast16_t maxoutpacketsize4 = size2buff4(USB_OTG_MAX_EP0_SIZE);
//uint_fast16_t base4;
uint_fast8_t numcontrolendpoints = 1;
uint_fast8_t numoutendpoints = 1;
// при addplaces = 3 появился звук на передаче в трансивер (при 2-х компортах)
// но если CDC и UAC включать поодиночке, обмен не нарушается и при 0.
// todo: найти все-таки документ
https://www.synopsys.com/ip_prototyping_kit...tgv2_drd_pc.pdf uint_fast8_t addplaces = 3;
#if WITHUSBUAC
numoutendpoints += 1;
#if WITHRTS96
enum { nuacinpackets = 1, nuacoutpackets = 1 };
#elif WITHRTS192
enum { nuacinpackets = 1, nuacoutpackets = 1 };
#else /* WITHRTS96 || WITHRTS192 */
enum { nuacinpackets = 2, nuacoutpackets = 2 };
#endif /* WITHRTS96 || WITHRTS192 */
const uint_fast16_t uacinmaxpacket = uasbd_getuacinmaxpacket();
maxoutpacketsize4 = ulmax16(maxoutpacketsize4, nuacoutpackets * size2buff4(VIRTUAL_AUDIO_PORT_DATA_SIZE_OUT));
#endif /* WITHUSBUAC */
#if WITHUSBCDC
numoutendpoints += 2;
#if WITHUSBUAC
#if WITHRTS96 || WITHRTS192
enum { ncdcindatapackets = 3, ncdcoutdatapackets = 4 };
#else /* WITHRTS96 || WITHRTS192 */
enum { ncdcindatapackets = 2, ncdcoutdatapackets = 2 };
#endif /* WITHRTS96 || WITHRTS192 */
#else /* WITHUSBUAC */
enum { ncdcindatapackets = 4, ncdcoutdatapackets = 4 };
#endif /* WITHUSBUAC */
maxoutpacketsize4 = ulmax16(maxoutpacketsize4, ncdcoutdatapackets * size2buff4(VIRTUAL_COM_PORT_DATA_SIZE));
#endif /* WITHUSBCDC */
#if WITHUSBCDCEEM
numoutendpoints += 1;
#if WITHUSBUAC
#if WITHRTS96 || WITHRTS192
enum { ncdceemindatapackets = 3, ncdceemoutdatapackets = 4 };
#else /* WITHRTS96 || WITHRTS192 */
enum { ncdceemindatapackets = 2, ncdceemoutdatapackets = 2 };
#endif /* WITHRTS96 || WITHRTS192 */
#else /* WITHUSBUAC */
enum { ncdceemindatapackets = 4, ncdceemoutdatapackets = 4 };
#endif /* WITHUSBUAC */
maxoutpacketsize4 = ulmax16(maxoutpacketsize4, ncdceemoutdatapackets * size2buff4(USBD_CDCEEM_BUFSIZE));
#endif /* WITHUSBCDCEEM */
uint_fast16_t base4;
uint_fast16_t size4;
{
/* Установить размер RX FIFO */
// (4 * number of control endpoints + 6) +
// ((largest USB packet used / 4) + 1 for status information) +
// (2 * number of OUT endpoints) +
// 1 for Global NAK
size4 =
(4 * numcontrolendpoints + 6) +
(maxoutpacketsize4 + 1) +
(2 * numoutendpoints) +
1 +
addplaces;
instance->GRXFSIZ = size4;
base4 = size4;
/* Установить размер TX FIFO EP0 */
size4 = 2 * (size2buff4(USB_OTG_MAX_EP0_SIZE) + 0);
instance->DIEPTXF0_HNPTXFSIZ = usbd_makefifoparam(base4, size4);
base4 += size4;
}
#if WITHUSBUAC
{
/* endpoint передачи звука в компютер */
const uint_fast8_t pipe = USBD_EP_ISOC_IN & 0x7F;
size4 = nuacinpackets * (size2buff4(uacinmaxpacket) + 0);
instance->DIEPTXF [pipe - 1] = usbd_makefifoparam(base4, size4);
base4 += size4;
}
#endif /* WITHUSBUAC */
#if WITHUSBCDC
{
/* полнофункциональное устройство */
const uint_fast8_t pipe = USBD_EP_CDC_IN & 0x7F;
size4 = ncdcindatapackets * (size2buff4(VIRTUAL_COM_PORT_DATA_SIZE) + 0);
instance->DIEPTXF [pipe - 1] = usbd_makefifoparam(base4, size4);
base4 += size4;
}
/* Эти endpoints не используются для обмена */
size4 = 0x10;
instance->DIEPTXF [(USBD_EP_CDC_INT & 0x7F) - 1] = usbd_makefifoparam(base4, size4);
instance->DIEPTXF [(USBD_EP_CDC_INb & 0x7F) - 1] = usbd_makefifoparam(base4, size4);
instance->DIEPTXF [(USBD_EP_CDC_INTb & 0x7F) - 1] = usbd_makefifoparam(base4, size4);
#endif /* WITHUSBCDC */
#if WITHUSBCDCEEM
{
/* полнофункциональное устройство */
const uint_fast8_t pipe = USBD_EP_CDCEEM_IN & 0x7F;
size4 = ncdceemindatapackets * (size2buff4(USBD_CDCEEM_BUFSIZE) + 0);
instance->DIEPTXF [pipe - 1] = usbd_makefifoparam(base4, size4);
base4 += size4;
}
#endif /* WITHUSBCDCEEM */
USB_FlushRxFifo(instance);
USB_FlushTxFifoAll(instance);
if ((base4 * 4) > fullsize)
{
char b [32];
debug_printf_P(PSTR("usbd_fifo_initialize error: base4=%u, fullsize=%u\n"), (base4 * 4), fullsize);
local_snprintf_P(b, sizeof b / sizeof b [0], PSTR("used=%u"), (base4 * 4));
display_setcolors(COLOR_RED, BGCOLOR);
display_at(0, 0,

;
for (;;)
;
}
else
{
debug_printf_P(PSTR("usbd_fifo_initialize: base4=%u, fullsize=%u\n"), (base4 * 4), fullsize);
#if 0
// Диагностическая выдача использованного объёма FIFO RAM
char b [32];
local_snprintf_P(b, sizeof b / sizeof b [0], PSTR("used=%u"), (base4 * 4));
display_setcolors(COLOR_GREEN, BGCOLOR);
display_at(0, 0,

;
local_delay_ms(2000);
#endif
}
}