Че-то запарился с простой вещью, но нигде нет простого описания.
Именно, нужно прикрутить к EHCI хосту работу с усб флешками, сам стек высокого уровня позаимствовал у стм, просто уже рабочий проверенный и не сложный в отличие от всяческих libusb и иже с ними.
Собственно что мне нужно - процедуры чтения и записи bulk пакетов.
Энумерация производится нормально, получаю дескриптора интерфейса и двух конечных точек
Обмен по 0й точке мне понятен - передаем 8ми байтовый запрос и получаем ответ(если нужно)
Например установка адреса устройства:
/* data for Set Address command */
usbhSetupCommand[0] = 0x00000500 | ((0x7F & device_address) <<16);
usbhSetupCommand[1] = 0x00000000;
формируем стандартный запрос
usb_qtd1 = usbh_qtd_init(0x8, 0, SETUP_PID, usbhSetupCommand); задаем TD передачи запроса
usb_qtd2 = usbh_qtd_init(0x0, 1, IN_PID, 0);
usb_qtd1->nextQtd = (uint32_t)usb_qtd2;
/* Link the new descriptor to the and of the list */
usb_qh_ep0->nextQtd = (uint32_t)usb_qtd1; передаем его в очередь точки 0 запуская на выполнение
дальше идет проверка, выполнена-ли передача
Принимает тоже правильно
/* data for Get Descriptor command */
usbhSetupCommand[0] = 0x01000680;
usbhSetupCommand[1] = 0x00120000;
usb_qtd1 = usbh_qtd_init(0x8, 0, SETUP_PID, usbhSetupCommand);
usb_qtd2 = usbh_qtd_init(18, 0, IN_PID, (uint32_t*) device_descriptor);
usb_qtd3 = usbh_qtd_init(0x0, 1, OUT_PID, 0);
// link the transfer descriptors so they all get executed
usb_qtd1->nextQtd = (uint32_t)usb_qtd2;
usb_qtd2->nextQtd = (uint32_t)usb_qtd3;
/* Point the QH to the linked list of qTDs */
usbh_qh_ep0->nextQtd = (uint32_t)usb_qtd1;
Вопрос как работать с bulk пакетами? очереди usbh_qh_ep1 на передачу и usbh_qh_ep2 на прием проинициализированы.
Пробовал "в тупую"
CODE
USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *port,
USBH_HOST *phost,
uint8_t *buff,
uint16_t length,
uint8_t hc_num)
{
USBH_Status status;
uint32_t i, temp;
uint32_t core = (uint32_t)port->controllerID;
phost->qtd_bulk1 = usbh_qtd_reset(phost->qtd_bulk1->mallocPointer,0, 0, OUT_PID, 0);
phost->qtd_bulk2 = usbh_qtd_reset(phost->qtd_bulk2->mallocPointer,length, 1, IN_PID, (uint32_t *)buff);
phost->qtd_bulk1->nextQtd = (uint32_t)phost->qtd_bulk2;
TmpUSB_wait=0;
while(phost->usb_qh_ep2->qtdToken & 0x80) /* wait for active bit to clear */
{if (TmpUSB_wait++>10000000) break;}
/* Point the QH to the linked list of qTDs */
phost->usb_qh_ep0->nextQtd = (uint32_t)phost->qtd_bulk1;
/* Enable async schedule */
// USB_USBCMD(USB_MODULE) |= USB_USBCMD_ASE;
/* Wait for asynchronous schedule to enable */
// while (!(USB_USBSTS(USB_MODULE) & USB_USBSTS_AS));
/* Wait for transaction to complete and clear interrpt flag */
#ifdef USB_USE_INT
while (usb_utmi_int_flag == 0);
usb_utmi_int_flag = 0;
#else
TmpUSB_wait=0;
while(!(HW_USBC_USBSTS_RD(core) & BM_USBC_UH1_USBSTS_UI))
{if (TmpUSB_wait++>10000000) break;}
HW_USBC_USBSTS_WR(core, HW_USBC_USBSTS_RD(core) | BM_USBC_UH1_USBSTS_UI);
#endif
/* Wait until the active bit is cleared in the last qtd. */
TmpUSB_wait=0;
while(phost->qtd_ctrl2->qtdToken & 0x80)
{if (TmpUSB_wait++>10000000) break;}
/* Check for errors */
if(HW_USBC_USBSTS_RD(core) & BM_USBC_UH1_USBSTS_UEI)
{
temp = *(uint32_t *)((HW_USBC_ASYNCLISTADDR_RD(core)) + 0x18);
#ifdef DEBUG_PRINT
printf("ERROR!!!\n");
printf("qTD status = 0x%08x\n",temp);
#endif
}
else
{
//printf("Set configuration command complete!!\n\n");
#ifdef DEBUG_PRINT
printf("USBSTS = 0x%08x\n",(HW_USBC_USBSTS_RD(core)));
#endif
}
/* Clear the USB error bit */
HW_USBC_USBSTS_WR(core, HW_USBC_USBSTS_RD(core) | BM_USBC_UH1_USBSTS_UEI);
printf("BulkReceive - DAT-%s, LNG-%d\n",buff,length);
return USBH_OK;
}
Каким образом тут поступать? Смотрел исходники стм - там совсем другой контроллер - не годится, usblib от nxp - практически нереально разобраться - слишком много натолкано в стек и очень большая вложенность функций
