ST/USBHOST forked to add another HID handler for raw keyboard data to get more detail not available with current handlers (all pressed keys, all releases, and periodic updates)
Dependents: C64-stm429_discovery
Revision 5:fc157e6bd5a5, committed 2017-04-26
- Comitter:
- frq08711@LMECWL0871.LME.ST.COM
- Date:
- Wed Apr 26 18:11:37 2017 +0200
- Parent:
- 3:1c76b46ad779
- Child:
- 6:d3ac9e1c0035
- Commit message:
- update for hub support
Changed in this revision
--- a/USBHost/TARGET_STM/USBEndpoint_STM.cpp Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHost/TARGET_STM/USBEndpoint_STM.cpp Wed Apr 26 18:11:37 2017 +0200 @@ -19,10 +19,17 @@ #include "USBEndpoint.h" extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num); extern uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chn_num); +extern void HAL_HCD_DisableInt(HCD_HandleTypeDef* hhcd, uint8_t chn_num); +extern void HAL_HCD_EnableInt(HCD_HandleTypeDef* hhcd, uint8_t chn_num); + + void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir_, uint32_t size, uint8_t ep_number, HCTD* td_list_[2]) { + HCD_HandleTypeDef *hhcd; + uint32_t *addr; + hced = hced_; type = type_; dir = dir_; @@ -46,10 +53,14 @@ td_current = td_list[0]; td_next = td_list[1]; - + /* remove potential post pending from previous endpoint */ + ep_queue.get(0); intf_nb = 0; - + hhcd = (HCD_HandleTypeDef*)hced->hhcd; + addr = &((uint32_t *)hhcd->pData)[hced->ch_num]; + *addr = 0; state = USB_TYPE_IDLE; + speed =false; } void USBEndpoint::setSize(uint32_t size) { @@ -59,8 +70,14 @@ void USBEndpoint::setDeviceAddress(uint8_t addr) { + HCD_HandleTypeDef *hhcd; + uint8_t hcd_speed = HCD_SPEED_FULL; + /* fix me : small speed device with hub not supported + if (this->speed) hcd_speed = HCD_SPEED_LOW; */ + if (this->speed) USB_WARN("small speed device on hub not supported"); + MBED_ASSERT(HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, addr, hcd_speed, type, size)!=HAL_BUSY); this->device_address = addr; - HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, addr, HCD_SPEED_FULL, type, size); + } void USBEndpoint::setSpeed(uint8_t speed) @@ -70,19 +87,41 @@ -void USBEndpoint::setState(uint8_t st) { - if (st > 18) - return; - if (state == USB_TYPE_FREE) HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num); +void USBEndpoint::setState(USB_TYPE st) +{ + /* modify this state is possible only with a plug */ + if ((state == USB_TYPE_FREE)) return; - state = (USB_TYPE)st; + state = st; + if (st == USB_TYPE_FREE) { + HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef*)hced->hhcd; + uint32_t *addr = &((uint32_t *)hhcd->pData)[hced->ch_num]; + if ((*addr)&& (type!=INTERRUPT_ENDPOINT)) { + this->ep_queue.put((uint8_t*)1); + } + MBED_ASSERT(HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num)!=HAL_BUSY); + HAL_HCD_DisableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num); + *addr = 0; + + } + if ((st == USB_TYPE_ERROR) ) { + MBED_ASSERT(HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num)!=HAL_BUSY); + HAL_HCD_DisableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num); + + } + if ((st == USB_TYPE_ERROR) ) { + uint8_t hcd_speed = HCD_SPEED_FULL; + /* small speed device with hub not supported + if (this->speed) hcd_speed = HCD_SPEED_LOW;*/ + MBED_ASSERT(HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, 0, hcd_speed, type, size)!=HAL_BUSY); + } } extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num); extern uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chn_num); - + USB_TYPE USBEndpoint::queueTransfer() { HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef*)hced->hhcd; @@ -90,38 +129,36 @@ uint32_t type = HAL_HCD_HC_GetType(hhcd, hced->ch_num); uint32_t max_size = HAL_HCD_HC_GetMaxPacket(hhcd, hced->ch_num); /* if a packet is queue on disconnected ; no solution for now */ - if(*addr == (uint32_t) -1) { - /* set td as disconnected */ - td_current->state = USB_TYPE_DISCONNECTED; - return USB_TYPE_DISCONNECTED; + if ((state == USB_TYPE_FREE) ) { + td_current->state = USB_TYPE_FREE; + return USB_TYPE_FREE; } + ep_queue.get(0); MBED_ASSERT(*addr ==0); - if ((type == EP_TYPE_BULK) || (type== EP_TYPE_CTRL)) { - transfer_len = td_current->size <= max_size ? td_current->size : max_size; - transferred = td_current->size; - } else { - transfer_len = td_current->size; - transferred = td_current->size; - MBED_ASSERT(transferred <= (int)max_size); - } + transfer_len = td_current->size <= max_size ? td_current->size : max_size; buf_start = (uint8_t *)td_current->currBufPtr; //Now add this free TD at this end of the queue state = USB_TYPE_PROCESSING; /* one request */ td_current->nextTD = (hcTd*)0; +#if defined(MAX_NYET_RETRY) td_current->retry = 0; +#endif + td_current->setup = setup; *addr = (uint32_t)td_current; /* dir /setup is inverted for ST */ /* token is useful only ctrl endpoint */ /* last parameter is ping ? */ MBED_ASSERT(HAL_HCD_HC_SubmitRequest((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num, dir-1, type,!setup,(uint8_t*) td_current->currBufPtr, transfer_len, 0)==HAL_OK); + HAL_HCD_EnableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num); + return USB_TYPE_PROCESSING; } void USBEndpoint::unqueueTransfer(volatile HCTD * td) { - + if (state==USB_TYPE_FREE) return; uint32_t *addr = &((uint32_t *)((HCD_HandleTypeDef*)hced->hhcd)->pData)[hced->ch_num]; td->state=0; td->currBufPtr=0;
--- a/USBHost/TARGET_STM/USBHALHost_STM.cpp Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHost/TARGET_STM/USBHALHost_STM.cpp Wed Apr 26 18:11:37 2017 +0200 @@ -26,52 +26,44 @@ { USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData); USBHALHost *obj= priv->inst; - int i; void (USBHALHost::*func)(int hub, int port, bool lowSpeed, USBHostHub * hub_parent ) = priv->deviceConnected; - for (i=0; i<MAX_ENDPOINT; i++) - if (priv->addr[i]==(uint32_t)-1)priv->addr[i]=0; - (obj->*func)(0,1,1,NULL); + (obj->*func)(0,1,0,NULL); } void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) { USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData); USBHALHost *obj= priv->inst; void (USBHALHost::*func1)(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr)= priv->deviceDisconnected; - void (USBHALHost::*func2)(volatile uint32_t addr)= priv->transferCompleted; - int i; (obj->*func1)(0,1,(USBHostHub *)NULL,0); - - /* fix me call with same frame number */ - /* all on going transaction must end and any new one must be rejected */ - for (i=0; i<MAX_ENDPOINT; i++) { - uint32_t addr = priv->addr[i]; - priv->addr[i]=(uint32_t)-1; - if ((addr!=(uint32_t)-1)&& (addr!=0)){ - HCTD *td = (HCTD *)addr; - td->currBufPtr +=HAL_HCD_HC_GetXferCount(hhcd, i); - td->state = USB_TYPE_DISCONNECTED; - (obj->*func2)(addr); - } - } - for (i=1; i< MAX_ENDPOINT;i++)HAL_HCD_HC_Halt(hhcd,i); } int HAL_HCD_HC_GetDirection(HCD_HandleTypeDef *hhcd,uint8_t chnum) { -/* useful for transmission */ - return hhcd->hc[chnum].ep_is_in; + /* useful for transmission */ + return hhcd->hc[chnum].ep_is_in; } uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd,uint8_t chnum) { -/* useful for transmission */ - return hhcd->hc[chnum].max_packet; + /* useful for transmission */ + return hhcd->hc[chnum].max_packet; +} + +void HAL_HCD_EnableInt(HCD_HandleTypeDef *hhcd,uint8_t chnum) +{ + USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; + USBx_HOST->HAINTMSK |= (1 << chnum); } +void HAL_HCD_DisableInt(HCD_HandleTypeDef *hhcd,uint8_t chnum) +{ + USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; + USBx_HOST->HAINTMSK &= ~(1 << chnum); +} uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd,uint8_t chnum) { -/* useful for transmission */ - return hhcd->hc[chnum].ep_type; + /* useful for transmission */ + return hhcd->hc[chnum].ep_type; } void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd,uint8_t chnum, HCD_URBStateTypeDef urb_state) @@ -79,118 +71,152 @@ USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData); USBHALHost *obj= priv->inst; void (USBHALHost::*func)(volatile uint32_t addr)= priv->transferCompleted; + uint32_t addr = priv->addr[chnum]; uint32_t max_size = HAL_HCD_HC_GetMaxPacket(hhcd, chnum); uint32_t type = HAL_HCD_HC_GetType(hhcd, chnum); uint32_t dir = HAL_HCD_HC_GetDirection(hhcd,chnum); uint32_t length; - if ((addr!=(uint32_t)-1) && (addr!=0)) { + if ( (addr!=0)) { HCTD *td = (HCTD *)addr; - /* put the state */ - if ((urb_state == URB_IDLE) && (type == EP_TYPE_INTR) ) { - length = td->size; - MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , 1,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK); - return; - } - td->state = (urb_state == URB_DONE) ? USB_TYPE_IDLE : USB_TYPE_ERROR; - /* move buffer pointer , for size */ - if ((type != EP_TYPE_BULK) && (type != EP_TYPE_CTRL )) { - /* in packet */ - } else { - if (urb_state == URB_DONE) { - /* reset retry counter */ - td->retry = 0; - if (td->size > max_size) { - /* enqueue another request */ - td->currBufPtr += max_size; - td->size -= max_size; - length = td->size <= max_size ? td->size : max_size; - MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , 1,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK); - return; - } - }else if (urb_state == URB_NOTREADY) { - /* try again */ - /* abritary limit , to avoid dead lock if other error than - * slow response is */ - if (td->retry < 1000) { - /* increment retry counter */ - td->retry++; - length = td->size <= max_size ? td->size : max_size; - MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , 1,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK); - return; - }else USB_ERR("urb_state != URB_NOTREADY"); - + if ((type == EP_TYPE_BULK) || (type == EP_TYPE_CTRL )) { + switch (urb_state) { + case URB_DONE: +#if defined(MAX_NYET_RETRY) + td->retry = 0; +#endif + if (td->size > max_size) { + /* enqueue another request */ + td->currBufPtr += max_size; + td->size -= max_size; + length = td->size <= max_size ? td->size : max_size; + MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , !td->setup,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK); + HAL_HCD_EnableInt(hhcd, chnum); + return; + } + break; + case URB_NOTREADY: + /* try again */ + /* abritary limit , to avoid dead lock if other error than + * slow response is */ +#if defined(MAX_NYET_RETRY) + if (td->retry < MAX_NYET_RETRY) { + /* increment retry counter */ + td->retry++; +#endif + length = td->size <= max_size ? td->size : max_size; + MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , !td->setup,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK); + HAL_HCD_EnableInt(hhcd, chnum); + return; +#if defined(MAX_NYET_RETRY) + } else USB_ERR("urb_state != URB_NOTREADY"); +#endif + break; } } - td->state = (urb_state == URB_DONE) ? USB_TYPE_IDLE : USB_TYPE_ERROR; + if ((type == EP_TYPE_INTR) ) { + /* reply a packet of length NULL, this will be analyse in call back + * for mouse or hub */ + td->state =USB_TYPE_IDLE ; + HAL_HCD_DisableInt(hhcd, chnum); + + } else { + td->state = (urb_state == URB_DONE) ? USB_TYPE_IDLE : USB_TYPE_ERROR; + } td->currBufPtr +=HAL_HCD_HC_GetXferCount(hhcd, chnum); - priv->addr[chnum]=0; (obj->*func)(addr); - } - else - { - USB_DBG_EVENT("spurious %d %d",chnum, urb_state); + } else { + if (urb_state !=0) + USB_DBG_EVENT("spurious %d %d",chnum, urb_state); } } + USBHALHost * USBHALHost::instHost; -void USBHALHost::init() { +void USBHALHost::init() +{ NVIC_DisableIRQ(USBHAL_IRQn); NVIC_SetVector(USBHAL_IRQn, (uint32_t)(_usbisr)); HAL_HCD_Init((HCD_HandleTypeDef *) usb_hcca); NVIC_EnableIRQ(USBHAL_IRQn); + control_disable = 0; HAL_HCD_Start((HCD_HandleTypeDef *) usb_hcca); usb_vbus(1); } -uint32_t USBHALHost::controlHeadED() { +uint32_t USBHALHost::controlHeadED() +{ + return 0xffffffff; +} + +uint32_t USBHALHost::bulkHeadED() +{ return 0xffffffff; } -uint32_t USBHALHost::bulkHeadED() { - return 0xffffffff; +uint32_t USBHALHost::interruptHeadED() +{ + return 0xffffffff; } -uint32_t USBHALHost::interruptHeadED() { - return 0xffffffff; -} - -void USBHALHost::updateBulkHeadED(uint32_t addr) { +void USBHALHost::updateBulkHeadED(uint32_t addr) +{ } -void USBHALHost::updateControlHeadED(uint32_t addr) { +void USBHALHost::updateControlHeadED(uint32_t addr) +{ } -void USBHALHost::updateInterruptHeadED(uint32_t addr) { +void USBHALHost::updateInterruptHeadED(uint32_t addr) +{ } -void USBHALHost::enableList(ENDPOINT_TYPE type) { -} - - -bool USBHALHost::disableList(ENDPOINT_TYPE type) { - return true; +void USBHALHost::enableList(ENDPOINT_TYPE type) +{ + /* react when the 3 lists are requested to be disabled */ + if (type == CONTROL_ENDPOINT) { + control_disable--; + if (control_disable==0) + NVIC_EnableIRQ(USBHAL_IRQn); + else printf("reent\n"); + } } -void USBHALHost::memInit() { - usb_hcca = (volatile HCD_HandleTypeDef *)usb_buf; +bool USBHALHost::disableList(ENDPOINT_TYPE type) +{ + if (type == CONTROL_ENDPOINT) { + NVIC_DisableIRQ(USBHAL_IRQn); + control_disable++; + if (control_disable>1) + printf("disable reentrance !!!\n"); + return true; + } + return false; +} + + +void USBHALHost::memInit() +{ + usb_hcca = (volatile HCD_HandleTypeDef *)usb_buf; usb_edBuf = usb_buf + HCCA_SIZE; usb_tdBuf = usb_buf + HCCA_SIZE +(MAX_ENDPOINT*ED_SIZE); - /* init channel */ - for (int i=0; i < MAX_ENDPOINT; i++) { - HCED *hced = (HCED*)(usb_edBuf + i*ED_SIZE); - hced->ch_num = i; - hced->hhcd = (HCCA *) usb_hcca; - } + /* init channel */ + memset((void*)usb_buf,0, TOTAL_SIZE); + for (int i=0; i < MAX_ENDPOINT; i++) { + HCED *hced = (HCED*)(usb_edBuf + i*ED_SIZE); + hced->ch_num = i; + hced->hhcd = (HCCA *) usb_hcca; + } } -volatile uint8_t * USBHALHost::getED() { +volatile uint8_t * USBHALHost::getED() +{ for (int i = 0; i < MAX_ENDPOINT; i++) { if ( !edBufAlloc[i] ) { edBufAlloc[i] = true; @@ -201,7 +227,8 @@ return NULL; //Could not alloc ED } -volatile uint8_t * USBHALHost::getTD() { +volatile uint8_t * USBHALHost::getTD() +{ int i; for (i = 0; i < MAX_TD; i++) { if ( !tdBufAlloc[i] ) { @@ -214,33 +241,38 @@ } -void USBHALHost::freeED(volatile uint8_t * ed) { +void USBHALHost::freeED(volatile uint8_t * ed) +{ int i; i = (ed - usb_edBuf) / ED_SIZE; edBufAlloc[i] = false; } -void USBHALHost::freeTD(volatile uint8_t * td) { +void USBHALHost::freeTD(volatile uint8_t * td) +{ int i; i = (td - usb_tdBuf) / TD_SIZE; tdBufAlloc[i] = false; } -void USBHALHost::resetRootHub() { +void USBHALHost::resetRootHub() +{ // Initiate port reset wait(0.2); HAL_HCD_ResetPort((HCD_HandleTypeDef *)usb_hcca); } -void USBHALHost::_usbisr(void) { +void USBHALHost::_usbisr(void) +{ if (instHost) { instHost->UsbIrqhandler(); } } -void USBHALHost::UsbIrqhandler() { +void USBHALHost::UsbIrqhandler() +{ HAL_HCD_IRQHandler((HCD_HandleTypeDef *)usb_hcca); } #endif
--- a/USBHost/USBEndpoint.h Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHost/USBEndpoint.h Wed Apr 26 18:11:37 2017 +0200 @@ -33,6 +33,9 @@ * Constructor */ USBEndpoint() { +#ifdef USBHOST_OTHER + speed = false; +#endif state = USB_TYPE_FREE; nextEp = NULL; }; @@ -111,7 +114,11 @@ // setters +#ifdef USBHOST_OTHER + void setState(USB_TYPE st); +#else inline void setState(USB_TYPE st) { state = st; } +#endif void setState(uint8_t st); void setDeviceAddress(uint8_t addr); inline void setLengthTransferred(int len) { transferred = len; };
--- a/USBHost/USBHALHost.h Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHost/USBHALHost.h Wed Apr 26 18:11:37 2017 +0200 @@ -164,6 +164,10 @@ bool volatile edBufAlloc[MAX_ENDPOINT]; bool volatile tdBufAlloc[MAX_TD]; +#ifdef USBHOST_OTHER + int control_disable; +#endif + }; #endif
--- a/USBHost/USBHost.cpp Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHost/USBHost.cpp Wed Apr 26 18:11:37 2017 +0200 @@ -46,7 +46,8 @@ * - when the usb_thread receives the event, it: * - call the callback attached to the endpoint where the td is attached */ -void USBHost::usb_process() { +void USBHost::usb_process() +{ bool controlListState; bool bulkListState; @@ -79,110 +80,123 @@ too_many_hub = false; buf[4] = 0; - do - { - Lock lock(this); + do { + Lock lock(this); + bool hub_unplugged = true; - for (i = 0; i < MAX_DEVICE_CONNECTED; i++) { - if (!deviceInUse[i]) { - USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]); - devices[i].init(usb_msg->hub, usb_msg->port, usb_msg->lowSpeed); - deviceReset[i] = false; - deviceInited[i] = true; - break; - } - } + int idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent)); + /* check that hub is connected to root port */ + if (usb_msg->hub_parent) { + /* a hub device must be present */ + for (k = 0; k < MAX_HUB_NB; k++) { + if ((&hubs[k] == usb_msg->hub_parent) && (hub_in_use[k])) + hub_unplugged=false; + } + } else hub_unplugged = false; - if (i == MAX_DEVICE_CONNECTED) { - USB_ERR("Too many device connected!!\r\n"); - continue; - } + if (((idx!=-1) && deviceInUse[idx] ) || ((idx == -1) && hub_unplugged)) + break; - if (!controlEndpointAllocated) { - control = newEndpoint(CONTROL_ENDPOINT, OUT, 0x08, 0x00); - addEndpoint(NULL, 0, (USBEndpoint*)control); - controlEndpointAllocated = true; - } + for (i =0 ; i < MAX_DEVICE_CONNECTED; i++) { + if (!deviceInUse[i]) { + USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]); + devices[i].init(usb_msg->hub, usb_msg->port, usb_msg->lowSpeed); + deviceReset[i] = false; + deviceInited[i] = true; + break; + } + } - #if MAX_HUB_NB - if (usb_msg->hub_parent) - devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent)); - #endif + if (i == MAX_DEVICE_CONNECTED) { + USB_ERR("Too many device connected!!\r\n"); + continue; + } - for (j = 0; j < timeout_set_addr; j++) { - - resetDevice(&devices[i]); - - // set size of control endpoint - devices[i].setSizeControlEndpoint(8); + if (!controlEndpointAllocated) { + control = newEndpoint(CONTROL_ENDPOINT, OUT, 0x08, 0x00); + addEndpoint(NULL, 0, (USBEndpoint*)control); + controlEndpointAllocated = true; + } - devices[i].activeAddress(false); +#if MAX_HUB_NB + if (usb_msg->hub_parent) + devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent)); +#endif - // get first 8 bit of device descriptor - // and check if we deal with a hub - USB_DBG("usb_thread read device descriptor on dev: %p\r\n", &devices[i]); - res = getDeviceDescriptor(&devices[i], buf, 8); + for (j = 0; j < timeout_set_addr; j++) { + + resetDevice(&devices[i]); - if (res != USB_TYPE_OK) { - USB_ERR("usb_thread could not read dev descr"); - continue; - } + // set size of control endpoint + devices[i].setSizeControlEndpoint(8); + + devices[i].activeAddress(false); - // set size of control endpoint - devices[i].setSizeControlEndpoint(buf[7]); + // get first 8 bit of device descriptor + // and check if we deal with a hub + USB_DBG("usb_thread read device descriptor on dev: %p\r\n", &devices[i]); + res = getDeviceDescriptor(&devices[i], buf, 8); - // second step: set an address to the device - res = setAddress(&devices[i], devices[i].getAddress()); + if (res != USB_TYPE_OK) { + USB_ERR("usb_thread could not read dev descr"); + continue; + } - if (res != USB_TYPE_OK) { - USB_ERR("SET ADDR FAILED"); - continue; - } - devices[i].activeAddress(true); - USB_DBG("Address of %p: %d", &devices[i], devices[i].getAddress()); + // set size of control endpoint + devices[i].setSizeControlEndpoint(buf[7]); + + // second step: set an address to the device + res = setAddress(&devices[i], devices[i].getAddress()); - // try to read again the device descriptor to check if the device - // answers to its new address - res = getDeviceDescriptor(&devices[i], buf, 8); + if (res != USB_TYPE_OK) { + USB_ERR("SET ADDR FAILED"); + continue; + } + devices[i].activeAddress(true); + USB_DBG("Address of %p: %d", &devices[i], devices[i].getAddress()); - if (res == USB_TYPE_OK) { - break; - } + // try to read again the device descriptor to check if the device + // answers to its new address + res = getDeviceDescriptor(&devices[i], buf, 8); - Thread::wait(100); - } + if (res == USB_TYPE_OK) { + break; + } - USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port); + Thread::wait(100); + } - #if MAX_HUB_NB - if (buf[4] == HUB_CLASS) { - for (k = 0; k < MAX_HUB_NB; k++) { - if (hub_in_use[k] == false) { - for (uint8_t j = 0; j < MAX_TRY_ENUMERATE_HUB; j++) { - if (hubs[k].connect(&devices[i])) { - devices[i].hub = &hubs[k]; - hub_in_use[k] = true; - break; - } - } - if (hub_in_use[k] == true) - break; - } - } + USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port); - if (k == MAX_HUB_NB) { - USB_ERR("Too many hubs connected!!\r\n"); - too_many_hub = true; - } - } +#if MAX_HUB_NB + if (buf[4] == HUB_CLASS) { + for (k = 0; k < MAX_HUB_NB; k++) { + if (hub_in_use[k] == false) { + for (uint8_t j = 0; j < MAX_TRY_ENUMERATE_HUB; j++) { + if (hubs[k].connect(&devices[i])) { + devices[i].hub = &hubs[k]; + hub_in_use[k] = true; + break; + } + } + if (hub_in_use[k] == true) + break; + } + } - if (usb_msg->hub_parent) - ((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]); - #endif + if (k == MAX_HUB_NB) { + USB_ERR("Too many hubs connected!!\r\n"); + too_many_hub = true; + } + } - if ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) { - deviceInUse[i] = true; - } + if (usb_msg->hub_parent) + ((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]); +#endif + + if ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) { + deviceInUse[i] = true; + } } while(0); @@ -191,22 +205,22 @@ // a device has been disconnected case DEVICE_DISCONNECTED_EVENT: - do - { - Lock lock(this); + do { + Lock lock(this); - controlListState = disableList(CONTROL_ENDPOINT); - bulkListState = disableList(BULK_ENDPOINT); - interruptListState = disableList(INTERRUPT_ENDPOINT); + controlListState = disableList(CONTROL_ENDPOINT); + bulkListState = disableList(BULK_ENDPOINT); + interruptListState = disableList(INTERRUPT_ENDPOINT); - idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent)); - if (idx != -1) { - freeDevice((USBDeviceConnected*)&devices[idx]); - } + idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent)); + if (idx != -1) { + freeDevice((USBDeviceConnected*)&devices[idx]); + deviceInited[idx]=false; + } - if (controlListState) enableList(CONTROL_ENDPOINT); - if (bulkListState) enableList(BULK_ENDPOINT); - if (interruptListState) enableList(INTERRUPT_ENDPOINT); + if (controlListState) enableList(CONTROL_ENDPOINT); + if (bulkListState) enableList(BULK_ENDPOINT); + if (interruptListState) enableList(INTERRUPT_ENDPOINT); } while(0); @@ -236,6 +250,12 @@ if (deviceInUse[idx]) { USB_WARN("td %p processed but not in idle state: %s [ep: %p - dev: %p - %s]", usb_msg->td_addr, ep->getStateString(), ep, ep->dev, ep->dev->getName(ep->getIntfNb())); ep->setState(USB_TYPE_IDLE); + /* as error, on interrupt endpoint can be + * reported, call the call back registered , + * if device still in use, this call back + * shall ask again an interrupt request. + */ + ep->call(); } } } @@ -282,12 +302,12 @@ USBHost::Lock::Lock(USBHost* pHost) : m_pHost(pHost) { - m_pHost->usb_mutex.lock(); + m_pHost->usb_mutex.lock(); } USBHost::Lock::~Lock() { - m_pHost->usb_mutex.unlock(); + m_pHost->usb_mutex.unlock(); } void USBHost::transferCompleted(volatile uint32_t addr) @@ -340,7 +360,7 @@ usb_msg->td_state = state; mail_usb_event.put(usb_msg); } - ep->setState(state); + ep->setState((USB_TYPE)state); ep->ep_queue.put((uint8_t*)1); } } @@ -363,12 +383,16 @@ /* virtual */ void USBHost::deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent) { // be sure that the new device connected is not already connected... + disableList(CONTROL_ENDPOINT); + int idx = findDevice(hub, port, hub_parent); if (idx != -1) { - if (deviceInited[idx]) + if (deviceInited[idx]) { + enableList(CONTROL_ENDPOINT); + return; + } } - message_t * usb_msg = mail_usb_event.alloc(); usb_msg->event_id = DEVICE_CONNECTED_EVENT; usb_msg->hub = hub; @@ -376,6 +400,9 @@ usb_msg->lowSpeed = lowSpeed; usb_msg->hub_parent = hub_parent; mail_usb_event.put(usb_msg); + enableList(CONTROL_ENDPOINT); + + } /* @@ -385,11 +412,17 @@ /* virtual */ void USBHost::deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr) { // be sure that the device disconnected is connected... + + disableList(CONTROL_ENDPOINT); + int idx = findDevice(hub, port, hub_parent); if (idx != -1) { - if (!deviceInUse[idx]) + if (!deviceInUse[idx]) { + enableList(CONTROL_ENDPOINT); return; + } } else { + enableList(CONTROL_ENDPOINT); return; } @@ -399,6 +432,9 @@ usb_msg->port = port; usb_msg->hub_parent = hub_parent; mail_usb_event.put(usb_msg); + enableList(CONTROL_ENDPOINT); + + } void USBHost::freeDevice(USBDeviceConnected * dev) @@ -695,14 +731,14 @@ volatile HCTD * hctd = NULL; const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : - ((type == CONTROL_ENDPOINT) ? "CONTROL" : "ISOCHRONOUS")); + ((type == CONTROL_ENDPOINT) ? "CONTROL" : "ISOCHRONOUS")); printf("State of %s:\r\n", type_str); while (hced != NULL) { uint8_t dir = ((hced->control & (3 << 11)) >> 11); printf("hced: %p [ADDR: %d, DIR: %s, EP_NB: 0x%X]\r\n", hced, - hced->control & 0x7f, - (dir == 1) ? "OUT" : ((dir == 0) ? "FROM_TD":"IN"), - (hced->control & (0xf << 7)) >> 7); + hced->control & 0x7f, + (dir == 1) ? "OUT" : ((dir == 0) ? "FROM_TD":"IN"), + (hced->control & (0xf << 7)) >> 7); hctd = (HCTD *)((uint32_t)(hced->headTD) & ~(0xf)); while (hctd != hced->tailTD) { printf("\thctd: %p [DIR: %s]\r\n", hctd, ((hctd->control & (3 << 19)) >> 19) == 1 ? "OUT" : "IN"); @@ -720,7 +756,7 @@ USB_TYPE USBHost::addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len) { USB_TYPE ret=USB_TYPE_PROCESSING; - td_mutex.lock(); + td_mutex.lock(); // allocate a TD which will be freed in TDcompletion volatile HCTD * td = ed->getNextTD(); @@ -728,7 +764,7 @@ return USB_TYPE_ERROR; } -#ifndef USBHOST_OTHER +#ifndef USBHOST_OTHER uint32_t token = (ed->isSetup() ? TD_SETUP : ( (ed->getDir() == IN) ? TD_IN : TD_OUT )); uint32_t td_toggle; @@ -754,10 +790,10 @@ printList(type); enableList(type); #else - /* call method specific for endpoint */ - td->currBufPtr = buf; - td->size = len; - ret = ed->queueTransfer(); + /* call method specific for endpoint */ + td->currBufPtr = buf; + td->size = len; + ret = ed->queueTransfer(); #endif td_mutex.unlock(); @@ -770,10 +806,10 @@ USB_TYPE USBHost::getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_dev_descr) { USB_TYPE t = controlRead( dev, - USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, - GET_DESCRIPTOR, - (DEVICE_DESCRIPTOR << 8) | (0), - 0, buf, MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf)); + USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, + GET_DESCRIPTOR, + (DEVICE_DESCRIPTOR << 8) | (0), + 0, buf, MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf)); if (len_dev_descr) *len_dev_descr = MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf); @@ -812,7 +848,8 @@ } -USB_TYPE USBHost::setAddress(USBDeviceConnected * dev, uint8_t address) { +USB_TYPE USBHost::setAddress(USBDeviceConnected * dev, uint8_t address) +{ return controlWrite( dev, USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_ADDRESS, @@ -830,7 +867,8 @@ 0, NULL, 0); } -uint8_t USBHost::numberDriverAttached(USBDeviceConnected * dev) { +uint8_t USBHost::numberDriverAttached(USBDeviceConnected * dev) +{ int index = findDevice(dev); uint8_t cnt = 0; if (index == -1) @@ -848,76 +886,75 @@ uint16_t total_conf_descr_length = 0; USB_TYPE res; - do - { - Lock lock(this); + do { + Lock lock(this); - // don't enumerate a device which all interfaces are registered to a specific driver - int index = findDevice(dev); + // don't enumerate a device which all interfaces are registered to a specific driver + int index = findDevice(dev); - if (index == -1) { - return USB_TYPE_ERROR; - } + if (index == -1) { + return USB_TYPE_ERROR; + } - uint8_t nb_intf_attached = numberDriverAttached(dev); - USB_DBG("dev: %p nb_intf: %d", dev, dev->getNbIntf()); - USB_DBG("dev: %p nb_intf_attached: %d", dev, nb_intf_attached); - if ((nb_intf_attached != 0) && (dev->getNbIntf() == nb_intf_attached)) { - USB_DBG("Don't enumerate dev: %p because all intf are registered with a driver", dev); - return USB_TYPE_OK; - } + uint8_t nb_intf_attached = numberDriverAttached(dev); + USB_DBG("dev: %p nb_intf: %d", dev, dev->getNbIntf()); + USB_DBG("dev: %p nb_intf_attached: %d", dev, nb_intf_attached); + if ((nb_intf_attached != 0) && (dev->getNbIntf() == nb_intf_attached)) { + USB_DBG("Don't enumerate dev: %p because all intf are registered with a driver", dev); + return USB_TYPE_OK; + } + + USB_DBG("Enumerate dev: %p", dev); - USB_DBG("Enumerate dev: %p", dev); - - // third step: get the whole device descriptor to see vid, pid - res = getDeviceDescriptor(dev, data, DEVICE_DESCRIPTOR_LENGTH); + // third step: get the whole device descriptor to see vid, pid + res = getDeviceDescriptor(dev, data, DEVICE_DESCRIPTOR_LENGTH); - if (res != USB_TYPE_OK) { - USB_DBG("GET DEV DESCR FAILED"); - return res; - } + if (res != USB_TYPE_OK) { + USB_DBG("GET DEV DESCR FAILED"); + return res; + } + + dev->setClass(data[4]); + dev->setSubClass(data[5]); + dev->setProtocol(data[6]); + dev->setVid(data[8] | (data[9] << 8)); + dev->setPid(data[10] | (data[11] << 8)); + USB_DBG("CLASS: %02X \t VID: %04X \t PID: %04X", data[4], data[8] | (data[9] << 8), data[10] | (data[11] << 8)); - dev->setClass(data[4]); - dev->setSubClass(data[5]); - dev->setProtocol(data[6]); - dev->setVid(data[8] | (data[9] << 8)); - dev->setPid(data[10] | (data[11] << 8)); - USB_DBG("CLASS: %02X \t VID: %04X \t PID: %04X", data[4], data[8] | (data[9] << 8), data[10] | (data[11] << 8)); + pEnumerator->setVidPid( data[8] | (data[9] << 8), data[10] | (data[11] << 8) ); - pEnumerator->setVidPid( data[8] | (data[9] << 8), data[10] | (data[11] << 8) ); + res = getConfigurationDescriptor(dev, data, sizeof(data), &total_conf_descr_length); + if (res != USB_TYPE_OK) { + return res; + } - res = getConfigurationDescriptor(dev, data, sizeof(data), &total_conf_descr_length); - if (res != USB_TYPE_OK) { - return res; - } +#if (DEBUG > 3) + USB_DBG("CONFIGURATION DESCRIPTOR:\r\n"); + for (int i = 0; i < total_conf_descr_length; i++) + printf("%02X ", data[i]); + printf("\r\n\r\n"); +#endif - #if (DEBUG > 3) - USB_DBG("CONFIGURATION DESCRIPTOR:\r\n"); - for (int i = 0; i < total_conf_descr_length; i++) - printf("%02X ", data[i]); - printf("\r\n\r\n"); - #endif + // Parse the configuration descriptor + parseConfDescr(dev, data, total_conf_descr_length, pEnumerator); - // Parse the configuration descriptor - parseConfDescr(dev, data, total_conf_descr_length, pEnumerator); + // only set configuration if not enumerated before + if (!dev->isEnumerated()) { - // only set configuration if not enumerated before - if (!dev->isEnumerated()) { - - USB_DBG("Set configuration 1 on dev: %p", dev); - // sixth step: set configuration (only 1 supported) - res = setConfiguration(dev, 1); + USB_DBG("Set configuration 1 on dev: %p", dev); + // sixth step: set configuration (only 1 supported) + res = setConfiguration(dev, 1); - if (res != USB_TYPE_OK) { - USB_DBG("SET CONF FAILED"); - return res; - } - } + if (res != USB_TYPE_OK) { + USB_DBG("SET CONF FAILED"); + return res; + } + } - dev->setEnumerated(); + dev->setEnumerated(); - // Now the device is enumerated! - USB_DBG("dev %p is enumerated\r\n", dev); + // Now the device is enumerated! + USB_DBG("dev %p is enumerated\r\n", dev); } while(0); @@ -1016,7 +1053,8 @@ return generalTransfer(dev, ep, buf, len, blocking, INTERRUPT_ENDPOINT, false); } -USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking, ENDPOINT_TYPE type, bool write) { +USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking, ENDPOINT_TYPE type, bool write) +{ #if DEBUG_TRANSFER const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : "ISOCHRONOUS"); @@ -1064,8 +1102,20 @@ res = addTransfer(ep, buf, len); if ((blocking)&& (res == USB_TYPE_PROCESSING)) { - +#ifdef USBHOST_OTHER + osEvent event = ep->ep_queue.get(TD_TIMEOUT); + if (event.status == osEventTimeout) + { + /* control endpoint is confusing for merge on b */ + disableList(CONTROL_ENDPOINT); + ep->setState(USB_TYPE_ERROR); + ep->ep_queue.get(0); + ep->unqueueTransfer(ep->getProcessedTD()); + enableList(CONTROL_ENDPOINT); + } +#else ep->ep_queue.get(); +#endif res = ep->getState(); USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep); @@ -1082,11 +1132,13 @@ } -USB_TYPE USBHost::controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) { +USB_TYPE USBHost::controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) +{ return controlTransfer(dev, requestType, request, value, index, buf, len, false); } -USB_TYPE USBHost::controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) { +USB_TYPE USBHost::controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) +{ return controlTransfer(dev, requestType, request, value, index, buf, len, true); } @@ -1120,7 +1172,20 @@ control->setNextToken(TD_SETUP); res = addTransfer(control, (uint8_t*)setupPacket, 8); - if (res == USB_TYPE_PROCESSING) control->ep_queue.get(); + if (res == USB_TYPE_PROCESSING) +#ifdef USBHOST_OTHER + { osEvent event = control->ep_queue.get(TD_TIMEOUT_CTRL); + if (event.status == osEventTimeout) { + disableList(CONTROL_ENDPOINT); + control->setState(USB_TYPE_ERROR); + control->ep_queue.get(0); + control->unqueueTransfer(control->getProcessedTD()); + enableList(CONTROL_ENDPOINT); + } + } +#else + control->ep_queue.get(); +#endif res = control->getState(); USB_DBG_TRANSFER("CONTROL setup stage %s", control->getStateString()); @@ -1134,7 +1199,21 @@ control->setNextToken(token); res = addTransfer(control, (uint8_t *)buf, length_transfer); - if (res == USB_TYPE_PROCESSING) control->ep_queue.get(); + if (res == USB_TYPE_PROCESSING) +#ifdef USBHOST_OTHER + { osEvent event = control->ep_queue.get(TD_TIMEOUT_CTRL); + if (event.status == osEventTimeout) + { + disableList(CONTROL_ENDPOINT); + control->setState(USB_TYPE_ERROR); + control->ep_queue.get(0); + control->unqueueTransfer(control->getProcessedTD()); + enableList(CONTROL_ENDPOINT); + } + } +#else + control->ep_queue.get(); +#endif res = control->getState(); #if DEBUG_TRANSFER @@ -1160,8 +1239,22 @@ token = (write) ? TD_IN : TD_OUT; control->setNextToken(token); res = addTransfer(control, NULL, 0); - - if (res == USB_TYPE_PROCESSING) control->ep_queue.get(); + if (res == USB_TYPE_PROCESSING) +#ifdef USBHOST_OTHER + { + osEvent event = control->ep_queue.get(TD_TIMEOUT_CTRL); + if (event.status == osEventTimeout) + { + disableList(CONTROL_ENDPOINT); + control->setState(USB_TYPE_ERROR); + control->ep_queue.get(0); + control->unqueueTransfer(control->getProcessedTD()); + enableList(CONTROL_ENDPOINT); + } + } +#else + control->ep_queue.get(); +#endif res = control->getState(); USB_DBG_TRANSFER("CONTROL ack stage %s", control->getStateString());
--- a/USBHost/USBHostConf.h Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHost/USBHostConf.h Wed Apr 26 18:11:37 2017 +0200 @@ -22,17 +22,17 @@ * to the usb host */ /* hub + 2 devices */ -#define MAX_DEVICE_CONNECTED 3 +#define MAX_DEVICE_CONNECTED 5 /* * Maximum of Hub connected to the usb host */ -#define MAX_HUB_NB 0 +#define MAX_HUB_NB 3 /* * Maximum number of ports on a USB hub */ -#define MAX_HUB_PORT 2 +#define MAX_HUB_PORT 4 /* * Enable USBHostMSD
--- a/USBHost/USBHostTypes.h Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHost/USBHostTypes.h Wed Apr 26 18:11:37 2017 +0200 @@ -18,7 +18,7 @@ #define USB_INC_H #include "mbed.h" -#include "toolchain.h" +#include "mbed_toolchain.h" enum USB_TYPE { USB_TYPE_OK = 0, @@ -117,6 +117,8 @@ #else +#define TD_TIMEOUT_CTRL 100 +#define TD_TIMEOUT 2000 #define TD_SETUP (uint32_t)(0) // Direction of Setup Packet #define TD_IN (uint32_t)(0x00100000) // Direction In #define TD_OUT (uint32_t)(0x00080000) // Direction Out @@ -158,6 +160,7 @@ __IO uint32_t size; // size of buffer void * ep; // ep address where a td is linked in __IO uint32_t retry; + __IO uint32_t setup; } PACKED HCTD; // ----------- HostController EndPoint Descriptor ------------- typedef struct hcEd {
--- a/USBHostHID/USBHostKeyboard.cpp Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHostHID/USBHostKeyboard.cpp Wed Apr 26 18:11:37 2017 +0200 @@ -99,7 +99,8 @@ } -bool USBHostKeyboard::connect() { +bool USBHostKeyboard::connect() +{ if (dev_connected) { return true; @@ -112,16 +113,23 @@ break; if (keyboard_device_found) { - int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN); + { + /* As this is done in a specific thread + * this lock is taken to avoid to process the device + * disconnect in usb process during the device registering */ + USBHost::Lock Lock(host); - if (!int_in) - break; + int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN); - USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf); - dev->setName("Keyboard", keyboard_intf); - host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init); + if (!int_in) + break; - int_in->attach(this, &USBHostKeyboard::rxHandler); + USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf); + dev->setName("Keyboard", keyboard_intf); + host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init); + + int_in->attach(this, &USBHostKeyboard::rxHandler); + } host->interruptRead(dev, int_in, report, int_in->getSize(), false); dev_connected = true;
--- a/USBHostHID/USBHostMouse.cpp Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHostHID/USBHostMouse.cpp Wed Apr 26 18:11:37 2017 +0200 @@ -46,7 +46,8 @@ return dev_connected; } -bool USBHostMouse::connect() { +bool USBHostMouse::connect() +{ int len_listen; if (dev_connected) { @@ -58,25 +59,32 @@ if(host->enumerate(dev, this)) break; - if (mouse_device_found) { - - int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN); - if (!int_in) - break; + { + /* As this is done in a specific thread + * this lock is taken to avoid to process the device + * disconnect in usb process during the device registering */ + USBHost::Lock Lock(host); + int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN); + if (!int_in) + break; - USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf); - dev->setName("Mouse", mouse_intf); - host->registerDriver(dev, mouse_intf, this, &USBHostMouse::init); + USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf); + dev->setName("Mouse", mouse_intf); + host->registerDriver(dev, mouse_intf, this, &USBHostMouse::init); - int_in->attach(this, &USBHostMouse::rxHandler); - len_listen = int_in->getSize(); - if (len_listen > sizeof(report)) { - len_listen = sizeof(report); + int_in->attach(this, &USBHostMouse::rxHandler); + len_listen = int_in->getSize(); + if (len_listen > sizeof(report)) { + len_listen = sizeof(report); + } } - host->interruptRead(dev, int_in, report, len_listen, false); - - dev_connected = true; + int ret=host->interruptRead(dev, int_in, report, len_listen, false); + MBED_ASSERT((ret==USB_TYPE_OK) || (ret ==USB_TYPE_PROCESSING) || (ret == USB_TYPE_FREE)); + if ((ret==USB_TYPE_OK) || (ret ==USB_TYPE_PROCESSING)) + dev_connected = true; + if (ret == USB_TYPE_FREE) + dev_connected = false; return true; } } @@ -86,33 +94,37 @@ } void USBHostMouse::rxHandler() { - int len_listen = int_in->getSize(); + int len_listen = int_in->getLengthTransferred(); + if (len_listen !=0) { - if (onUpdate) { - (*onUpdate)(report[0] & 0x07, report[1], report[2], report[3]); - } + if (onUpdate) { + (*onUpdate)(report[0] & 0x07, report[1], report[2], report[3]); + } - if (onButtonUpdate && (buttons != (report[0] & 0x07))) { - (*onButtonUpdate)(report[0] & 0x07); - } + if (onButtonUpdate && (buttons != (report[0] & 0x07))) { + (*onButtonUpdate)(report[0] & 0x07); + } - if (onXUpdate && (x != report[1])) { - (*onXUpdate)(report[1]); - } + if (onXUpdate && (x != report[1])) { + (*onXUpdate)(report[1]); + } - if (onYUpdate && (y != report[2])) { - (*onYUpdate)(report[2]); - } + if (onYUpdate && (y != report[2])) { + (*onYUpdate)(report[2]); + } - if (onZUpdate && (z != report[3])) { - (*onZUpdate)(report[3]); + if (onZUpdate && (z != report[3])) { + (*onZUpdate)(report[3]); + } + + // update mouse state + buttons = report[0] & 0x07; + x = report[1]; + y = report[2]; + z = report[3]; } - - // update mouse state - buttons = report[0] & 0x07; - x = report[1]; - y = report[2]; - z = report[3]; + /* set again the maximum value */ + len_listen = int_in->getSize(); if (len_listen > sizeof(report)) { len_listen = sizeof(report);
--- a/USBHostHID/USBHostMouse.h Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHostHID/USBHostMouse.h Wed Apr 26 18:11:37 2017 +0200 @@ -113,8 +113,7 @@ USBHost * host; USBDeviceConnected * dev; USBEndpoint * int_in; - uint8_t report[4]; - + uint8_t report[64]; bool dev_connected; bool mouse_device_found; int mouse_intf;
--- a/USBHostHub/USBHostHub.cpp Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHostHub/USBHostHub.cpp Wed Apr 26 18:11:37 2017 +0200 @@ -180,7 +180,7 @@ void USBHostHub::rxHandler() { uint32_t status; if (int_in) { - if (int_in->getState() == USB_TYPE_IDLE) { + if ((int_in->getLengthTransferred())&&(int_in->getState() == USB_TYPE_IDLE)) { for (int port = 1; port <= nb_port; port++) { status = getPortStatus(port); USB_DBG("[hub handler hub: %d] status port %d [hub: %p]: 0x%X", dev->getHub(), port, dev, status); @@ -227,6 +227,9 @@ #endif while(1) { status = getPortStatus(port); + /* disconnection since reset request */ + if (!(status & PORT_CONNECTION)) + break; if (status & (PORT_ENABLE | PORT_RESET)) break; if (status & PORT_OVER_CURRENT) {
--- a/USBHostMSD/USBHostMSD.cpp Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHostMSD/USBHostMSD.cpp Wed Apr 26 18:11:37 2017 +0200 @@ -17,7 +17,6 @@ #include "USBHostMSD.h" #if USBHOST_MSD - #include "dbg.h" #define CBW_SIGNATURE 0x43425355 @@ -29,13 +28,16 @@ #define GET_MAX_LUN (0xFE) #define BO_MASS_STORAGE_RESET (0xFF) -USBHostMSD::USBHostMSD(const char * rootdir) : FATFileSystem(rootdir) +USBHostMSD::USBHostMSD() { host = USBHost::getHostInst(); - init(); + /* register an object in FAT */ + + init_usb(); } -void USBHostMSD::init() { +void USBHostMSD::init_usb() +{ dev_connected = false; dev = NULL; bulk_in = NULL; @@ -72,6 +74,11 @@ break; if (msd_device_found) { + /* As this is done in a specific thread + * this lock is taken to avoid to process a disconnection in + * usb process during the device registering */ + USBHost::Lock Lock(host); + bulk_in = dev->getEndpoint(msd_intf, BULK_ENDPOINT, IN); bulk_out = dev->getEndpoint(msd_intf, BULK_ENDPOINT, OUT); @@ -80,14 +87,14 @@ USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, msd_intf); dev->setName("MSD", msd_intf); - host->registerDriver(dev, msd_intf, this, &USBHostMSD::init); + host->registerDriver(dev, msd_intf, this, &USBHostMSD::init_usb); dev_connected = true; return true; } } //if() } //for() - init(); + init_usb(); return false; } @@ -99,9 +106,9 @@ /*virtual*/ bool USBHostMSD::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed { if ((msd_intf == -1) && - (intf_class == MSD_CLASS) && - (intf_subclass == 0x06) && - (intf_protocol == 0x50)) { + (intf_class == MSD_CLASS) && + (intf_subclass == 0x06) && + (intf_protocol == 0x50)) { msd_intf = intf_nb; return true; } @@ -122,13 +129,15 @@ } -int USBHostMSD::testUnitReady() { +int USBHostMSD::testUnitReady() +{ USB_DBG("Test unit ready"); return SCSITransfer(NULL, 6, DEVICE_TO_HOST, 0, 0); } -int USBHostMSD::readCapacity() { +int USBHostMSD::readCapacity() +{ USB_DBG("Read capacity"); uint8_t cmd[10] = {0x25,0,0,0,0,0,0,0,0,0}; uint8_t result[8]; @@ -136,13 +145,14 @@ if (status == 0) { blockCount = (result[0] << 24) | (result[1] << 16) | (result[2] << 8) | result[3]; blockSize = (result[4] << 24) | (result[5] << 16) | (result[6] << 8) | result[7]; - USB_INFO("MSD [dev: %p] - blockCount: %lu, blockSize: %d,Capacity: %llu\r\n", dev, blockCount, blockSize,(uint64_t)blockCount*(uint64_t)blockSize); + USB_INFO("MSD [dev: %p] - blockCount: %u, blockSize: %d, Capacity: %d\r\n", dev, blockCount, blockSize, blockCount*blockSize); } return status; } -int USBHostMSD::SCSIRequestSense() { +int USBHostMSD::SCSIRequestSense() +{ USB_DBG("Request sense"); uint8_t cmd[6] = {0x03,0,0,0,18,0}; uint8_t result[18]; @@ -151,7 +161,8 @@ } -int USBHostMSD::inquiry(uint8_t lun, uint8_t page_code) { +int USBHostMSD::inquiry(uint8_t lun, uint8_t page_code) +{ USB_DBG("Inquiry"); uint8_t evpd = (page_code == 0) ? 0 : 1; uint8_t cmd[6] = {0x12, uint8_t((lun << 5) | evpd), page_code, 0, 36, 0}; @@ -174,7 +185,8 @@ return status; } -int USBHostMSD::checkResult(uint8_t res, USBEndpoint * ep) { +int USBHostMSD::checkResult(uint8_t res, USBEndpoint * ep) +{ // if ep stalled: send clear feature if (res == USB_TYPE_STALL_ERROR) { res = host->controlWrite( dev, @@ -183,6 +195,7 @@ 0, ep->getAddress(), NULL, 0); // set state to IDLE if clear feature successful if (res == USB_TYPE_OK) { + USBHost::Lock Lock(host); ep->setState(USB_TYPE_IDLE); } } @@ -194,7 +207,8 @@ } -int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len) { +int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len) +{ int res = 0; @@ -277,7 +291,8 @@ } -int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction) { +int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction) +{ uint8_t cmd[10]; memset(cmd,0,10); cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A; @@ -293,7 +308,8 @@ return SCSITransfer(cmd, 10, direction, buf, blockSize*nbBlock); } -int USBHostMSD::getMaxLun() { +int USBHostMSD::getMaxLun() +{ uint8_t buf[1], res; res = host->controlRead( dev, USB_RECIPIENT_INTERFACE | USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS, 0xfe, 0, msd_intf, buf, 1); @@ -301,12 +317,11 @@ return res; } -int USBHostMSD::disk_initialize() { +int USBHostMSD::init() +{ USB_DBG("FILESYSTEM: init"); - uint16_t i, timeout = 10; - + uint16_t i, timeout = 10, ret; getMaxLun(); - for (i = 0; i < timeout; i++) { Thread::wait(100); if (!testUnitReady()) @@ -323,12 +338,17 @@ return readCapacity(); } -int USBHostMSD::disk_write(const uint8_t* buffer, uint32_t block_number, uint32_t count) { +int USBHostMSD::program(const void *buffer, bd_addr_t addr, bd_size_t size) +{ + uint32_t block_number, count; if (!disk_init) { - disk_initialize(); + init(); } if (!disk_init) return -1; + block_number = addr / blockSize; + count = size /blockSize; + for (uint32_t b = block_number; b < block_number + count; b++) { if (dataTransfer((uint8_t*)buffer, b, 1, HOST_TO_DEVICE)) return -1; @@ -337,13 +357,17 @@ return 0; } -int USBHostMSD::disk_read(uint8_t* buffer, uint32_t block_number, uint32_t count) { - USB_DBG("FILESYSTEM: read block: %lld, count: %d", block_number, count); +int USBHostMSD::read(void *buffer, bd_addr_t addr, bd_size_t size) +{ + uint32_t block_number, count; if (!disk_init) { - disk_initialize(); + init(); } if (!disk_init) return -1; + block_number = addr / blockSize; + count = size /blockSize; + for (uint32_t b = block_number; b < block_number + count; b++) { if (dataTransfer((uint8_t*)buffer, b, 1, DEVICE_TO_HOST)) return -1; @@ -352,14 +376,36 @@ return 0; } -uint32_t USBHostMSD::disk_sectors() { - USB_DBG("FILESYSTEM: sectors"); - if (!disk_init) { - disk_initialize(); - } +int USBHostMSD::erase(bd_addr_t addr, bd_size_t size) +{ + return 0; +} + +bd_size_t USBHostMSD::get_read_size() const +{ + if (!disk_init) + return -1; + return (bd_size_t)blockSize; +} + +bd_size_t USBHostMSD::get_program_size() const +{ + if (!disk_init) + return -1; + return (bd_size_t)blockSize; +} +bd_size_t USBHostMSD::get_erase_size() const +{ + if (!disk_init) + return -1; + return (bd_size_t)blockSize; +} + +bd_size_t USBHostMSD::size() const +{ + USB_DBG("FILESYSTEM: size "); if (!disk_init) return 0; - return blockCount; + return (bd_size_t)blockCount*(bd_size_t)blockSize; } - #endif
--- a/USBHostMSD/USBHostMSD.h Fri Feb 17 12:40:57 2017 +0100 +++ b/USBHostMSD/USBHostMSD.h Wed Apr 26 18:11:37 2017 +0200 @@ -23,24 +23,26 @@ #include "USBHost.h" #include "FATFileSystem.h" +#include "BlockDevice.h" /** * A class to communicate a USB flash disk */ -class USBHostMSD : public IUSBEnumerator, public FATFileSystem { +class USBHostMSD : public IUSBEnumerator, public BlockDevice +{ public: /** - * Constructor - * - * @param rootdir mount name - */ - USBHostMSD(const char * rootdir); + * Constructor + * + * @param rootdir mount name + */ + USBHostMSD(); /** - * Check if a MSD device is connected - * - * @return true if a MSD device is connected - */ + * Check if a MSD device is connected + * + * @return true if a MSD device is connected + */ bool connected(); /** @@ -49,6 +51,20 @@ * @return true if connection was successful */ bool connect(); + virtual int init(); + virtual int deinit() + { + return BD_ERROR_OK; + }; + virtual int read(void *buffer, bd_addr_t addr, bd_size_t size); + virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size); + virtual int erase(bd_addr_t addr, bd_size_t size); + virtual bd_size_t get_read_size() const; + virtual bd_size_t get_program_size() const; + virtual bd_size_t get_erase_size() const; + virtual bd_size_t size() const; + + protected: //From IUSBEnumerator @@ -56,13 +72,6 @@ virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used - // From FATFileSystem - virtual int disk_initialize(); - virtual int disk_status() {return 0;}; - virtual int disk_read(uint8_t* buffer, uint32_t sector, uint32_t count); - virtual int disk_write(const uint8_t* buffer, uint32_t sector, uint32_t count); - virtual int disk_sync() {return 0;}; - virtual uint32_t disk_sectors(); private: USBHost * host; @@ -110,7 +119,7 @@ bool msd_device_found; bool disk_init; - void init(); + void init_usb(); };