|
Работа с радиомышкой в МХ6, Куда копать - без понятия.. |
|
|
|
Aug 12 2015, 13:46
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(aaarrr @ Aug 12 2015, 15:28)  Не нужно в вашем случае никакой специфической инициализации. У вас есть какой-нибудь пример инициализации? Вот, что у меня- CODE int emuerateDevice(usb_module_t *port, usbhQueueHead_t *usb_qh_ep0, usbDeviceDescriptor_t *device_descriptor,uint8_t *config_descriptor,uint8_t *interface_descriptor, uint8_t *hid_descriptor,uint8_t *ep_descriptor,uint8_t *report_descriptor ) { usbh_bus_reset(port); hal_delay_us(500); //printf("Device reset.\n"); /*! * Read the first 8 bytes of the device descriptor as we do not yet know the max packet size\n * Our new device has address 0 at this time. */
usbh_get_dev_desc(port, usb_qh_ep0, device_descriptor); /*! * Update the maximum packet size in the queue head */
// Stop schedule to avoid contention with controller usbh_disable_asynchronous_schedule(port); // printf("Device 2\n"); /* Set the max packet size in the QH to the max packet size in the device descriptor */ usb_qh_ep0->endpointCharacteristics = ((usb_qh_ep0->endpointCharacteristics & ~USB_QH_EP_CHAR_MAX_PACKET(0x7FF)) | USB_QH_EP_CHAR_MAX_PACKET(device_descriptor->bMaxPacketSize));
usb_qh_ep0->endpointCharacteristics &= ~(0x7FF << 16); // clear max packet size usb_qh_ep0->endpointCharacteristics |= ((uint32_t)(device_descriptor->bMaxPacketSize)) << 16;
// Restart asynchronous schedule usbh_enable_asynchronous_schedule(port); /* Send set address command */ usbh_set_device_address(port, usb_qh_ep0, DEVICE_ADDRESS); /* Read in the full device descriptor */ usbh_get_dev_desc(port, usb_qh_ep0, device_descriptor); /* Read in the configuration descriptor */ usbh_get_config_desc(port, usb_qh_ep0, config_descriptor); /* Read in the interface, HID, and endpoint descriptors */ usbh_get_interface_desc(port, usb_qh_ep0, interface_descriptor,hid_descriptor,ep_descriptor); /* Test the interface descriptor parameters to check if the attached * device is in the HID class and that it is also a mouse. */ /* if( (interface_descriptor[5] != 0x3) | (interface_descriptor[7] != 0x2)) { //printf("Device enumerated.\n"); return 0; // not a mouse; return } */ /* Set the configuration for the device */ /* We already know the device is a USB mouse, so there is only one possible * configuration for the device. */
// Эт строка для смены интерфейса usbh_set_interface_desc(port, usb_qh_ep0, DEVICE_ADDRESS); usbh_set_configuration(port, usb_qh_ep0, CONFIG_VALUE); usbh_get_report_desc(port, usb_qh_ep0, report_descriptor); return 1; }
//сама процедура, по логике интерфейс должен измениться на 1 с 0го, но по факту ничего не работает
void usbh_set_interface_desc(usb_module_t *port, usbhQueueHead_t *usb_qh_ep0, uint32_t device_address) { usbhTransferDescriptor_t * usb_qtd1, *usb_qtd2; uint32_t temp; //uint32_t usbhSetupCommand[2]; uint32_t core = (uint32_t)port->controllerID; usbhSetupCommand[0] = 0x00011100; usbhSetupCommand[1] = 0x00000001; usb_qtd1 = usbh_qtd_init(0x8, 0, SETUP_PID, usbhSetupCommand); usb_qtd2 = usbh_qtd_init(0x0, 1, IN_PID, 0);
usb_qtd1->nextQtd = (uint32_t)usb_qtd2; TmpUSB_wait=0; while(usb_qh_ep0->qtdToken & 0x80) /* wait for active bit to clear */ {if (TmpUSB_wait++>100000) break;} /* Point the QH to the linked list of qTDs */ usb_qh_ep0->nextQtd = (uint32_t)usb_qtd1; /* 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++>100000) 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(usb_qtd2->qtdToken & 0x80) {if (TmpUSB_wait++>100000) break;}
/* Check for errors */ if(HW_USBC_USBSTS_RD(core) & BM_USBC_UH1_USBSTS_UEI) { printf("ERROR!!!\n"); temp = *(uint32_t *)((HW_USBC_ASYNCLISTADDR_RD(core)) + 0x18); printf("qTD status = 0x%08x\n",temp); } 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); }
Сообщение отредактировал mantech - Aug 12 2015, 13:53
|
|
|
|
|
Aug 12 2015, 15:04
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(aaarrr @ Aug 12 2015, 17:20)  Для работы со вторым интерфейсом нужно всего лишь брать данные с EP 2 IN 1h). Ничего инициализировать НЕ НУЖНО. Ещеб знать, как ее туда впихнуть... CODE usb_port_speed = usb_get_port_speed(usbhModule);
/*! * Create a QueueHead to use for EndPoint0. This single QH will be the\n * asynchronous schedule during enumeration. */ usbhMouse->usb_qh_ep0 = NULL; switch (usb_port_speed) { case usbSpeedFull: usbhMouse->usb_qh_ep0 = usbh_qh_init(0x40, 1, EPS_FULL, 0, 0, 0); // printf("Device connected at FULL speed\n"); break; case usbSpeedLow: usbhMouse->usb_qh_ep0 = usbh_qh_init(0x8, 1, EPS_LOW, 0, 0, 0); // printf("Device connected at LOW speed\n"); break; case usbSpeedHigh: usbhMouse->usb_qh_ep0 = usbh_qh_init(0x40, 1, EPS_HIGH, 0, 0, 0); // printf("Device connected at HIGH speed\n"); break; default : break; //error! restart host... } if (usbhMouse->usb_qh_ep0==NULL) {usbhMouse->hid_status=0;return;}
// Put this queue head on the Asynchronous Schedule.\n // This is our first queue head on the AS so we point the controller to this QH\n //Any further queue heads will be linked to this HQ.
HW_USBC_ASYNCLISTADDR_WR(usbhMouse->usb_core, (uint32_t)usbhMouse->usb_qh_ep0);
//! Enable the asynchronous schedule usbh_enable_asynchronous_schedule(usbhModule);
//! Enumerate the attached device // printf("\n enumeration...\n");
if (emuerateDevice(usbhModule, usbhMouse->usb_qh_ep0, usbhMouse->device_descriptor, usbhMouse->config_descriptor, usbhMouse->interface_descriptor,usbhMouse->hid_descriptor, usbhMouse->ep_descriptor, usbhMouse->report_descriptor )) ; // printf("USB mouse enumerated!!\n"); else { //printf("\nDevice is not a mouse. No further processing is performed\n"); usbhMouse->hid_status=2; //device unknown, detach required! return; }
// printf("Move mouse, and the mouse reports will be printed on the terminal.\n Press left button to exit.\n");
//! if we have a mouse connected. //! Initialize the periodic schedule for the interrupt endpoint if (usbhMouse->hid_num==0) { xmemset(frame_list1, 0, sizeof(frame_list1)); periodic_base = usbh_periodic_schedule_init(usbhModule, FRAME_LIST_SIZE, (&frame_list1[0])); } else { xmemset(frame_list2, 0, sizeof(frame_list2)); periodic_base = usbh_periodic_schedule_init(usbhModule, FRAME_LIST_SIZE, (&frame_list2[0])); } //! Create a queue head for endpoint 1 usbhMouse->usb_qh_ep1 = usbh_qh_init(0x8,0, EPS_LOW,1,DEVICE_ADDRESS,1); //! - Invalidate the QH horizontal pointer since the init function will point the QH back to itself. usbhMouse->usb_qh_ep1->queueHeadLinkPointer |= USB_QH_LINK_PTR_T;
/* This version of the code just polls the mouse once per iteration of * the frame list. The polling rate can be adjusted changing the size * of the frame list and/or pointing more of the frame list entries * to the interrupt QH. */
//! - Put the queue head on the periodic schedule *(uint32_t *)(periodic_base) = (uint32_t)usbhMouse->usb_qh_ep1 + 0x002;
/* * Initialize the amount of data to receive. In this case we will * receive 20 packets per loop. ep_desc[04] inidicates the size of * each packet. So transfer_size = 20 * ep_desc[04]. */ usbhMouse->int_packet_size = usbhMouse->ep_descriptor[04]; usbhMouse->int_transfer_size = 20 * usbhMouse->int_packet_size;
//! Create a qTD to transfer 20 packets worth of data usbhMouse->int_qtd = usbh_qtd_init(usbhMouse->int_transfer_size, 1, IN_PID, (uint32_t*) usbhMouse->usbhMouseData);
//! Activate the queue head to start polling the device /* * This while(1) loop will allow for continuously receiving mouse data. Some * packets could be lost due to the time needed to reinitialize the qTD for the * next batch of transfers. So a more correct way to do this would be to create * multiple qTDs and rotate them for each iteration of the loop. For a mouse * application some data loss is acceptable, so only one qTD is used. */ usbhMouse->usb_qh_ep1->nextQtd = (uint32_t) usbhMouse->int_qtd; usbhMouse->bytes_received = 0; usbhMouse->hid_status=3; //mouse installed! } else return; //device not attach } if (usbhMouse->hid_status==2) { //printf("\nDevice is not a mouse. No further processing is performed\n"); if (HW_USBC_PORTSC1_RD(usbhMouse->usb_core) & BM_USBC_UH1_PORTSC1_CCS); else usbhMouse->hid_status=0; }
|
|
|
|
|
Aug 12 2015, 15:40
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(aaarrr @ Aug 12 2015, 18:26)  Начните с перекапывания usbh_get_interface_desc() - он, я так подозреваю, возвращает первый попавшийся дескриптор интерфейса, а нужно чтобы возвращал правильный. Он получает сразу все, т.е. дескриптора конфигурации, там 1 конф, затем интерфейс 0, затем хид0, и кон.точку 0. Далее сразу интерфейс 1, затем хид1, и кон.точку 1. В поля пишется параметры инт 0. Но могу добавить смещение и будут писаться для инт 1 ЗЫ. Похоже все эти параметры нафиг не нужны для работы системы, кроме дескр кон.точки[4], берется размер пакета. Так что это где-то в настройках поллинга кон.точки, только без доков тут не разобраться...
Сообщение отредактировал mantech - Aug 12 2015, 15:52
|
|
|
|
|
Aug 12 2015, 18:46
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(aaarrr @ Aug 12 2015, 20:12)  Адрес точки тоже должен браться из дескриптора, поищите. Вряд ли его стали бы жестко устанавливать, хотя и такое можно представить. Но в любом случае какой-то адрес должен фигурировать при транзакции. Нет, не вижу вообще связи ничего, кроме длины репорта. ЗЫ. После анализа этого быдлокода, я уже все могу представить  Вообще, по-уму, где должна быть привязка кон. точек к системе опроса порта?
Сообщение отредактировал mantech - Aug 12 2015, 18:48
|
|
|
|
|
Aug 12 2015, 19:02
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(aaarrr @ Aug 12 2015, 21:58)  По-уму, код должен был бы распарсить интерфейсы, выбрать нужный (мышь), и из него взять номер точки. Ну хорошо, я распарсил его своим кодом, теперь в дескрипторах находятся только данные по интерфейсу мышки, я знаю его точку, и что дальше делать? ее же нужно поставить на опрос контроллера, а там полный мрак со всякими листами трансфер дескрипторов... HW_USBC_ASYNCLISTADDR_WR(usbhMouse->usb_core, (uint32_t)usbhMouse->usb_qh_ep0); - здесь, я так понял, задается адрес КТ0 - основной в устройстве. Вот здесь - usbhMouse->usb_qh_ep1 = usbh_qh_init(0x8,0, EPS_LOW,1,DEVICE_ADDRESS,1); //! - Invalidate the QH horizontal pointer since the init function will point the QH back to itself. usbhMouse->usb_qh_ep1->queueHeadLinkPointer |= USB_QH_LINK_PTR_T; в параметрах нашел, что EPS_LOW,1,DEVICE_ADDRESS, "1" - это номер КТ Пробовал ставить 2 - не помогло. что вот это такое - usb_qh_ep1->queueHeadLinkPointer |= USB_QH_LINK_PTR_T; - без понятия вообще, в доках ет ничего.
Сообщение отредактировал mantech - Aug 12 2015, 19:05
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|