Merge pull request #4231 from jamike/USBH0ST_TARGET_STM_HUB_SUPPORT

USBHOST hub support for TARGET_STM
pull/4322/head
Martin Kojtal 2017-05-15 16:01:34 +01:00 committed by GitHub
commit d98da4089a
17 changed files with 757 additions and 458 deletions

View File

@ -19,10 +19,17 @@
#include "USBEndpoint.h" #include "USBEndpoint.h"
extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num); 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 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]) 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_; hced = hced_;
type = type_; type = type_;
dir = dir_; dir = dir_;
@ -46,10 +53,14 @@ void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir
td_current = td_list[0]; td_current = td_list[0];
td_next = td_list[1]; td_next = td_list[1];
/* remove potential post pending from previous endpoint */
ep_queue.get(0);
intf_nb = 0; intf_nb = 0;
hhcd = (HCD_HandleTypeDef*)hced->hhcd;
addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
*addr = 0;
state = USB_TYPE_IDLE; state = USB_TYPE_IDLE;
speed =false;
} }
void USBEndpoint::setSize(uint32_t size) void USBEndpoint::setSize(uint32_t size)
{ {
@ -59,8 +70,16 @@ void USBEndpoint::setSize(uint32_t size)
void USBEndpoint::setDeviceAddress(uint8_t addr) 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; 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) void USBEndpoint::setSpeed(uint8_t speed)
@ -70,12 +89,36 @@ void USBEndpoint::setSpeed(uint8_t speed)
void USBEndpoint::setState(uint8_t st) { void USBEndpoint::setState(USB_TYPE st)
if (st > 18) {
/* modify this state is possible only with a plug */
if (state == USB_TYPE_FREE) {
return; return;
if (state == USB_TYPE_FREE) HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num); }
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);
}
} }
@ -90,38 +133,38 @@ USB_TYPE USBEndpoint::queueTransfer()
uint32_t type = HAL_HCD_HC_GetType(hhcd, hced->ch_num); uint32_t type = HAL_HCD_HC_GetType(hhcd, hced->ch_num);
uint32_t max_size = HAL_HCD_HC_GetMaxPacket(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 a packet is queue on disconnected ; no solution for now */
if(*addr == (uint32_t) -1) { if (state == USB_TYPE_FREE) {
/* set td as disconnected */ td_current->state = USB_TYPE_FREE;
td_current->state = USB_TYPE_DISCONNECTED; return USB_TYPE_FREE;
return USB_TYPE_DISCONNECTED;
} }
ep_queue.get(0);
MBED_ASSERT(*addr ==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; 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);
}
buf_start = (uint8_t *)td_current->currBufPtr; buf_start = (uint8_t *)td_current->currBufPtr;
//Now add this free TD at this end of the queue //Now add this free TD at this end of the queue
state = USB_TYPE_PROCESSING; state = USB_TYPE_PROCESSING;
/* one request */ /* one request */
td_current->nextTD = (hcTd*)0; td_current->nextTD = (hcTd*)0;
#if defined(MAX_NYET_RETRY)
td_current->retry = 0;
#endif
td_current->setup = setup;
*addr = (uint32_t)td_current; *addr = (uint32_t)td_current;
/* dir /setup is inverted for ST */ /* dir /setup is inverted for ST */
/* token is useful only ctrl endpoint */ /* token is useful only ctrl endpoint */
/* last parameter is ping ? */ /* 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); 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; return USB_TYPE_PROCESSING;
} }
void USBEndpoint::unqueueTransfer(volatile HCTD * td) 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]; uint32_t *addr = &((uint32_t *)((HCD_HandleTypeDef*)hced->hhcd)->pData)[hced->ch_num];
td->state=0; td->state=0;
td->currBufPtr=0; td->currBufPtr=0;

View File

@ -26,51 +26,43 @@ void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
{ {
USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData); USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
USBHALHost *obj= priv->inst; USBHALHost *obj= priv->inst;
int i;
void (USBHALHost::*func)(int hub, int port, bool lowSpeed, USBHostHub * hub_parent ) = priv->deviceConnected; void (USBHALHost::*func)(int hub, int port, bool lowSpeed, USBHostHub * hub_parent ) = priv->deviceConnected;
for (i=0; i<MAX_ENDPOINT; i++) (obj->*func)(0,1,0,NULL);
if (priv->addr[i]==(uint32_t)-1)priv->addr[i]=0;
(obj->*func)(0,1,1,NULL);
} }
void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
{ {
USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData); USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
USBHALHost *obj= priv->inst; USBHALHost *obj= priv->inst;
void (USBHALHost::*func1)(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr)= priv->deviceDisconnected; 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); (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) int HAL_HCD_HC_GetDirection(HCD_HandleTypeDef *hhcd,uint8_t chnum)
{ {
/* useful for transmission */ /* useful for transmission */
return hhcd->hc[chnum].ep_is_in; return hhcd->hc[chnum].ep_is_in;
} }
uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd,uint8_t chnum) uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd,uint8_t chnum)
{ {
/* useful for transmission */ /* useful for transmission */
return hhcd->hc[chnum].max_packet; 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) uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd,uint8_t chnum)
{ {
/* useful for transmission */ /* useful for transmission */
return hhcd->hc[chnum].ep_type; return hhcd->hc[chnum].ep_type;
} }
@ -79,97 +71,149 @@ void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd,uint8_t chnum,
USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData); USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
USBHALHost *obj= priv->inst; USBHALHost *obj= priv->inst;
void (USBHALHost::*func)(volatile uint32_t addr)= priv->transferCompleted; void (USBHALHost::*func)(volatile uint32_t addr)= priv->transferCompleted;
uint32_t addr = priv->addr[chnum]; uint32_t addr = priv->addr[chnum];
uint32_t max_size = HAL_HCD_HC_GetMaxPacket(hhcd, chnum); uint32_t max_size = HAL_HCD_HC_GetMaxPacket(hhcd, chnum);
uint32_t type = HAL_HCD_HC_GetType(hhcd, chnum); uint32_t type = HAL_HCD_HC_GetType(hhcd, chnum);
uint32_t dir = HAL_HCD_HC_GetDirection(hhcd,chnum); uint32_t dir = HAL_HCD_HC_GetDirection(hhcd,chnum);
uint32_t length; uint32_t length;
if ((addr!=(uint32_t)-1) && (addr!=0)) { if ( (addr!=0)) {
HCTD *td = (HCTD *)addr; HCTD *td = (HCTD *)addr;
/* put the state */
if ((urb_state == URB_IDLE) && (type == EP_TYPE_INTR) ) { if ((type == EP_TYPE_BULK) || (type == EP_TYPE_CTRL )) {
length = td->size; switch (urb_state) {
MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , 1,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK); case URB_DONE:
return; #if defined(MAX_NYET_RETRY)
} td->retry = 0;
td->state = (urb_state == URB_DONE) ? USB_TYPE_IDLE : USB_TYPE_ERROR; #endif
if (urb_state == URB_NOTREADY)
USB_ERR("urb_state != URB_NOTREADY");
/* move buffer pointer , for size */
if ((type != EP_TYPE_BULK) && (type != EP_TYPE_CTRL )) {
/* in packet */
} else {
if (urb_state == URB_DONE) {
if (td->size > max_size) { if (td->size > max_size) {
/* enqueue another request */ /* enqueue another request */
td->currBufPtr += max_size; td->currBufPtr += max_size;
td->size -= max_size; td->size -= max_size;
length = td->size <= 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); 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; 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;
} }
} }
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->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 td->currBufPtr +=HAL_HCD_HC_GetXferCount(hhcd, chnum);
{ (obj->*func)(addr);
} else {
if (urb_state !=0) {
USB_DBG_EVENT("spurious %d %d",chnum, urb_state); USB_DBG_EVENT("spurious %d %d",chnum, urb_state);
} }
}
} }
USBHALHost * USBHALHost::instHost; USBHALHost * USBHALHost::instHost;
void USBHALHost::init() { void USBHALHost::init()
{
NVIC_DisableIRQ(USBHAL_IRQn); NVIC_DisableIRQ(USBHAL_IRQn);
NVIC_SetVector(USBHAL_IRQn, (uint32_t)(_usbisr)); NVIC_SetVector(USBHAL_IRQn, (uint32_t)(_usbisr));
HAL_HCD_Init((HCD_HandleTypeDef *) usb_hcca); HAL_HCD_Init((HCD_HandleTypeDef *) usb_hcca);
NVIC_EnableIRQ(USBHAL_IRQn); NVIC_EnableIRQ(USBHAL_IRQn);
control_disable = 0;
HAL_HCD_Start((HCD_HandleTypeDef *) usb_hcca); HAL_HCD_Start((HCD_HandleTypeDef *) usb_hcca);
usb_vbus(1); usb_vbus(1);
} }
uint32_t USBHALHost::controlHeadED() { uint32_t USBHALHost::controlHeadED()
{
return 0xffffffff; return 0xffffffff;
} }
uint32_t USBHALHost::bulkHeadED() { uint32_t USBHALHost::bulkHeadED()
{
return 0xffffffff; return 0xffffffff;
} }
uint32_t USBHALHost::interruptHeadED() { uint32_t USBHALHost::interruptHeadED()
{
return 0xffffffff; 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) { 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");
}
}
} }
bool USBHALHost::disableList(ENDPOINT_TYPE type) { 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 true;
}
return false;
} }
void USBHALHost::memInit() { void USBHALHost::memInit()
{
usb_hcca = (volatile HCD_HandleTypeDef *)usb_buf; usb_hcca = (volatile HCD_HandleTypeDef *)usb_buf;
usb_edBuf = usb_buf + HCCA_SIZE; usb_edBuf = usb_buf + HCCA_SIZE;
usb_tdBuf = usb_buf + HCCA_SIZE +(MAX_ENDPOINT*ED_SIZE); usb_tdBuf = usb_buf + HCCA_SIZE +(MAX_ENDPOINT*ED_SIZE);
/* init channel */ /* init channel */
memset((void*)usb_buf,0, TOTAL_SIZE);
for (int i=0; i < MAX_ENDPOINT; i++) { for (int i=0; i < MAX_ENDPOINT; i++) {
HCED *hced = (HCED*)(usb_edBuf + i*ED_SIZE); HCED *hced = (HCED*)(usb_edBuf + i*ED_SIZE);
hced->ch_num = i; hced->ch_num = i;
@ -177,7 +221,8 @@ void USBHALHost::memInit() {
} }
} }
volatile uint8_t * USBHALHost::getED() { volatile uint8_t * USBHALHost::getED()
{
for (int i = 0; i < MAX_ENDPOINT; i++) { for (int i = 0; i < MAX_ENDPOINT; i++) {
if ( !edBufAlloc[i] ) { if ( !edBufAlloc[i] ) {
edBufAlloc[i] = true; edBufAlloc[i] = true;
@ -188,7 +233,8 @@ volatile uint8_t * USBHALHost::getED() {
return NULL; //Could not alloc ED return NULL; //Could not alloc ED
} }
volatile uint8_t * USBHALHost::getTD() { volatile uint8_t * USBHALHost::getTD()
{
int i; int i;
for (i = 0; i < MAX_TD; i++) { for (i = 0; i < MAX_TD; i++) {
if ( !tdBufAlloc[i] ) { if ( !tdBufAlloc[i] ) {
@ -201,33 +247,38 @@ volatile uint8_t * USBHALHost::getTD() {
} }
void USBHALHost::freeED(volatile uint8_t * ed) { void USBHALHost::freeED(volatile uint8_t * ed)
{
int i; int i;
i = (ed - usb_edBuf) / ED_SIZE; i = (ed - usb_edBuf) / ED_SIZE;
edBufAlloc[i] = false; edBufAlloc[i] = false;
} }
void USBHALHost::freeTD(volatile uint8_t * td) { void USBHALHost::freeTD(volatile uint8_t * td)
{
int i; int i;
i = (td - usb_tdBuf) / TD_SIZE; i = (td - usb_tdBuf) / TD_SIZE;
tdBufAlloc[i] = false; tdBufAlloc[i] = false;
} }
void USBHALHost::resetRootHub() { void USBHALHost::resetRootHub()
{
// Initiate port reset // Initiate port reset
wait(0.2); wait(0.2);
HAL_HCD_ResetPort((HCD_HandleTypeDef *)usb_hcca); HAL_HCD_ResetPort((HCD_HandleTypeDef *)usb_hcca);
} }
void USBHALHost::_usbisr(void) { void USBHALHost::_usbisr(void)
{
if (instHost) { if (instHost) {
instHost->UsbIrqhandler(); instHost->UsbIrqhandler();
} }
} }
void USBHALHost::UsbIrqhandler() { void USBHALHost::UsbIrqhandler()
{
HAL_HCD_IRQHandler((HCD_HandleTypeDef *)usb_hcca); HAL_HCD_IRQHandler((HCD_HandleTypeDef *)usb_hcca);
} }
#endif #endif

View File

@ -33,6 +33,9 @@ public:
* Constructor * Constructor
*/ */
USBEndpoint() { USBEndpoint() {
#ifdef USBHOST_OTHER
speed = false;
#endif
state = USB_TYPE_FREE; state = USB_TYPE_FREE;
nextEp = NULL; nextEp = NULL;
}; };
@ -111,7 +114,11 @@ public:
// setters // setters
#ifdef USBHOST_OTHER
void setState(USB_TYPE st);
#else
inline void setState(USB_TYPE st) { state = st; } inline void setState(USB_TYPE st) { state = st; }
#endif
void setState(uint8_t st); void setState(uint8_t st);
void setDeviceAddress(uint8_t addr); void setDeviceAddress(uint8_t addr);
inline void setLengthTransferred(int len) { transferred = len; }; inline void setLengthTransferred(int len) { transferred = len; };

View File

@ -164,6 +164,10 @@ private:
bool volatile edBufAlloc[MAX_ENDPOINT]; bool volatile edBufAlloc[MAX_ENDPOINT];
bool volatile tdBufAlloc[MAX_TD]; bool volatile tdBufAlloc[MAX_TD];
#ifdef USBHOST_OTHER
int control_disable;
#endif
}; };
#endif #endif

View File

@ -46,7 +46,8 @@ USBHost * USBHost::instHost = NULL;
* - when the usb_thread receives the event, it: * - when the usb_thread receives the event, it:
* - call the callback attached to the endpoint where the td is attached * - call the callback attached to the endpoint where the td is attached
*/ */
void USBHost::usb_process() { void USBHost::usb_process()
{
bool controlListState; bool controlListState;
bool bulkListState; bool bulkListState;
@ -79,11 +80,28 @@ void USBHost::usb_process() {
too_many_hub = false; too_many_hub = false;
buf[4] = 0; buf[4] = 0;
do do {
{
Lock lock(this); Lock lock(this);
bool hub_unplugged = true;
for (i = 0; i < MAX_DEVICE_CONNECTED; i++) { 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 (((idx!=-1) && deviceInUse[idx] ) || ((idx == -1) && hub_unplugged)) {
break;
}
for (i =0 ; i < MAX_DEVICE_CONNECTED; i++) {
if (!deviceInUse[i]) { if (!deviceInUse[i]) {
USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]); USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]);
devices[i].init(usb_msg->hub, usb_msg->port, usb_msg->lowSpeed); devices[i].init(usb_msg->hub, usb_msg->port, usb_msg->lowSpeed);
@ -104,10 +122,11 @@ void USBHost::usb_process() {
controlEndpointAllocated = true; controlEndpointAllocated = true;
} }
#if MAX_HUB_NB #if MAX_HUB_NB
if (usb_msg->hub_parent) if (usb_msg->hub_parent) {
devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent)); devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent));
#endif }
#endif
for (j = 0; j < timeout_set_addr; j++) { for (j = 0; j < timeout_set_addr; j++) {
@ -154,7 +173,7 @@ void USBHost::usb_process() {
USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port); USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port);
#if MAX_HUB_NB #if MAX_HUB_NB
if (buf[4] == HUB_CLASS) { if (buf[4] == HUB_CLASS) {
for (k = 0; k < MAX_HUB_NB; k++) { for (k = 0; k < MAX_HUB_NB; k++) {
if (hub_in_use[k] == false) { if (hub_in_use[k] == false) {
@ -165,10 +184,11 @@ void USBHost::usb_process() {
break; break;
} }
} }
if (hub_in_use[k] == true) if (hub_in_use[k] == true) {
break; break;
} }
} }
}
if (k == MAX_HUB_NB) { if (k == MAX_HUB_NB) {
USB_ERR("Too many hubs connected!!\r\n"); USB_ERR("Too many hubs connected!!\r\n");
@ -176,9 +196,10 @@ void USBHost::usb_process() {
} }
} }
if (usb_msg->hub_parent) if (usb_msg->hub_parent) {
((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]); ((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]);
#endif }
#endif
if ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) { if ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) {
deviceInUse[i] = true; deviceInUse[i] = true;
@ -191,8 +212,7 @@ void USBHost::usb_process() {
// a device has been disconnected // a device has been disconnected
case DEVICE_DISCONNECTED_EVENT: case DEVICE_DISCONNECTED_EVENT:
do do {
{
Lock lock(this); Lock lock(this);
controlListState = disableList(CONTROL_ENDPOINT); controlListState = disableList(CONTROL_ENDPOINT);
@ -202,11 +222,18 @@ void USBHost::usb_process() {
idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent)); idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent));
if (idx != -1) { if (idx != -1) {
freeDevice((USBDeviceConnected*)&devices[idx]); freeDevice((USBDeviceConnected*)&devices[idx]);
deviceInited[idx]=false;
} }
if (controlListState) enableList(CONTROL_ENDPOINT); if (controlListState) {
if (bulkListState) enableList(BULK_ENDPOINT); enableList(CONTROL_ENDPOINT);
if (interruptListState) enableList(INTERRUPT_ENDPOINT); }
if (bulkListState) {
enableList(BULK_ENDPOINT);
}
if (interruptListState) {
enableList(INTERRUPT_ENDPOINT);
}
} while(0); } while(0);
@ -224,8 +251,9 @@ void USBHost::usb_process() {
if (ep->getDir() == IN) { if (ep->getDir() == IN) {
buf_transfer = ep->getBufStart(); buf_transfer = ep->getBufStart();
printf("READ SUCCESS [%d bytes transferred - td: 0x%08X] on ep: [%p - addr: %02X]: ", ep->getLengthTransferred(), usb_msg->td_addr, ep, ep->getAddress()); printf("READ SUCCESS [%d bytes transferred - td: 0x%08X] on ep: [%p - addr: %02X]: ", ep->getLengthTransferred(), usb_msg->td_addr, ep, ep->getAddress());
for (int i = 0; i < ep->getLengthTransferred(); i++) for (int i = 0; i < ep->getLengthTransferred(); i++) {
printf("%02X ", buf_transfer[i]); printf("%02X ", buf_transfer[i]);
}
printf("\r\n\r\n"); printf("\r\n\r\n");
} }
#endif #endif
@ -236,6 +264,12 @@ void USBHost::usb_process() {
if (deviceInUse[idx]) { 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())); 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); 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();
} }
} }
} }
@ -266,9 +300,10 @@ USBHost::USBHost() : usbThread(osPriorityNormal, USB_THREAD_STACK)
devices[i].setAddress(i + 1); devices[i].setAddress(i + 1);
deviceReset[i] = false; deviceReset[i] = false;
deviceInited[i] = false; deviceInited[i] = false;
for (uint8_t j = 0; j < MAX_INTF; j++) for (uint8_t j = 0; j < MAX_INTF; j++) {
deviceAttachedDriver[i][j] = false; deviceAttachedDriver[i][j] = false;
} }
}
#if MAX_HUB_NB #if MAX_HUB_NB
for (uint8_t i = 0; i < MAX_HUB_NB; i++) { for (uint8_t i = 0; i < MAX_HUB_NB; i++) {
@ -294,8 +329,9 @@ void USBHost::transferCompleted(volatile uint32_t addr)
{ {
uint8_t state; uint8_t state;
if(addr == 0) if(addr == 0) {
return; return;
}
volatile HCTD* tdList = NULL; volatile HCTD* tdList = NULL;
@ -315,20 +351,23 @@ void USBHost::transferCompleted(volatile uint32_t addr)
#ifdef USBHOST_OTHER #ifdef USBHOST_OTHER
state = ((HCTD *)td)->state; state = ((HCTD *)td)->state;
if (state == USB_TYPE_IDLE) if (state == USB_TYPE_IDLE) {
ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart()); ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
}
#else #else
if (((HCTD *)td)->control >> 28) { if (((HCTD *)td)->control >> 28) {
state = ((HCTD *)td)->control >> 28; state = ((HCTD *)td)->control >> 28;
} else { } else {
if (td->currBufPtr) if (td->currBufPtr) {
ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart()); ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
}
state = 16 /*USB_TYPE_IDLE*/; state = 16 /*USB_TYPE_IDLE*/;
} }
#endif #endif
if (state == USB_TYPE_IDLE) if (state == USB_TYPE_IDLE) {
ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart()); ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
}
ep->unqueueTransfer(td); ep->unqueueTransfer(td);
@ -340,7 +379,7 @@ void USBHost::transferCompleted(volatile uint32_t addr)
usb_msg->td_state = state; usb_msg->td_state = state;
mail_usb_event.put(usb_msg); mail_usb_event.put(usb_msg);
} }
ep->setState(state); ep->setState((USB_TYPE)state);
ep->ep_queue.put((uint8_t*)1); ep->ep_queue.put((uint8_t*)1);
} }
} }
@ -365,9 +404,10 @@ USBHost * USBHost::getHostInst()
// be sure that the new device connected is not already connected... // be sure that the new device connected is not already connected...
int idx = findDevice(hub, port, hub_parent); int idx = findDevice(hub, port, hub_parent);
if (idx != -1) { if (idx != -1) {
if (deviceInited[idx]) if (deviceInited[idx]) {
return; return;
} }
}
message_t * usb_msg = mail_usb_event.alloc(); message_t * usb_msg = mail_usb_event.alloc();
usb_msg->event_id = DEVICE_CONNECTED_EVENT; usb_msg->event_id = DEVICE_CONNECTED_EVENT;
@ -387,8 +427,9 @@ USBHost * USBHost::getHostInst()
// be sure that the device disconnected is connected... // be sure that the device disconnected is connected...
int idx = findDevice(hub, port, hub_parent); int idx = findDevice(hub, port, hub_parent);
if (idx != -1) { if (idx != -1) {
if (!deviceInUse[idx]) if (!deviceInUse[idx]) {
return; return;
}
} else { } else {
return; return;
} }
@ -422,8 +463,9 @@ void USBHost::freeDevice(USBDeviceConnected * dev)
} }
// notify hub parent that this device has been disconnected // notify hub parent that this device has been disconnected
if (dev->getHubParent()) if (dev->getHubParent()) {
dev->getHubParent()->deviceDisconnected(dev); dev->getHubParent()->deviceDisconnected(dev);
}
#endif #endif
@ -667,8 +709,9 @@ int USBHost::findDevice(uint8_t hub, uint8_t port, USBHostHub * hub_parent)
for (int i = 0; i < MAX_DEVICE_CONNECTED; i++) { for (int i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if (devices[i].getHub() == hub && devices[i].getPort() == port) { if (devices[i].getHub() == hub && devices[i].getPort() == port) {
if (hub_parent != NULL) { if (hub_parent != NULL) {
if (hub_parent == devices[i].getHubParent()) if (hub_parent == devices[i].getHubParent()) {
return i; return i;
}
} else { } else {
return i; return i;
} }
@ -774,8 +817,9 @@ USB_TYPE USBHost::getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, u
GET_DESCRIPTOR, GET_DESCRIPTOR,
(DEVICE_DESCRIPTOR << 8) | (0), (DEVICE_DESCRIPTOR << 8) | (0),
0, buf, MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf)); 0, buf, MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf));
if (len_dev_descr) if (len_dev_descr) {
*len_dev_descr = MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf); *len_dev_descr = MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf);
}
return t; return t;
} }
@ -799,8 +843,9 @@ USB_TYPE USBHost::getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t *
total_conf_descr_length = buf[2] | (buf[3] << 8); total_conf_descr_length = buf[2] | (buf[3] << 8);
total_conf_descr_length = MIN(max_len_buf, total_conf_descr_length); total_conf_descr_length = MIN(max_len_buf, total_conf_descr_length);
if (len_conf_descr) if (len_conf_descr) {
*len_conf_descr = total_conf_descr_length; *len_conf_descr = total_conf_descr_length;
}
USB_DBG("TOTAL_LENGTH: %d \t NUM_INTERF: %d", total_conf_descr_length, buf[4]); USB_DBG("TOTAL_LENGTH: %d \t NUM_INTERF: %d", total_conf_descr_length, buf[4]);
@ -812,7 +857,8 @@ USB_TYPE USBHost::getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t *
} }
USB_TYPE USBHost::setAddress(USBDeviceConnected * dev, uint8_t address) { USB_TYPE USBHost::setAddress(USBDeviceConnected * dev, uint8_t address)
{
return controlWrite( dev, return controlWrite( dev,
USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE,
SET_ADDRESS, SET_ADDRESS,
@ -830,15 +876,18 @@ USB_TYPE USBHost::setConfiguration(USBDeviceConnected * dev, uint8_t conf)
0, NULL, 0); 0, NULL, 0);
} }
uint8_t USBHost::numberDriverAttached(USBDeviceConnected * dev) { uint8_t USBHost::numberDriverAttached(USBDeviceConnected * dev)
{
int index = findDevice(dev); int index = findDevice(dev);
uint8_t cnt = 0; uint8_t cnt = 0;
if (index == -1) if (index == -1) {
return 0; return 0;
}
for (uint8_t i = 0; i < MAX_INTF; i++) { for (uint8_t i = 0; i < MAX_INTF; i++) {
if (deviceAttachedDriver[index][i]) if (deviceAttachedDriver[index][i]) {
cnt++; cnt++;
} }
}
return cnt; return cnt;
} }
@ -848,8 +897,7 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
uint16_t total_conf_descr_length = 0; uint16_t total_conf_descr_length = 0;
USB_TYPE res; USB_TYPE res;
do do {
{
Lock lock(this); Lock lock(this);
// don't enumerate a device which all interfaces are registered to a specific driver // don't enumerate a device which all interfaces are registered to a specific driver
@ -891,12 +939,13 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
return res; return res;
} }
#if (DEBUG > 3) #if (DEBUG > 3)
USB_DBG("CONFIGURATION DESCRIPTOR:\r\n"); USB_DBG("CONFIGURATION DESCRIPTOR:\r\n");
for (int i = 0; i < total_conf_descr_length; i++) for (int i = 0; i < total_conf_descr_length; i++) {
printf("%02X ", data[i]); printf("%02X ", data[i]);
}
printf("\r\n\r\n"); printf("\r\n\r\n");
#endif #endif
// Parse the configuration descriptor // Parse the configuration descriptor
parseConfDescr(dev, data, total_conf_descr_length, pEnumerator); parseConfDescr(dev, data, total_conf_descr_length, pEnumerator);
@ -1016,7 +1065,8 @@ USB_TYPE USBHost::interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint
return generalTransfer(dev, ep, buf, len, blocking, INTERRUPT_ENDPOINT, false); 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 #if DEBUG_TRANSFER
const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : "ISOCHRONOUS"); const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : "ISOCHRONOUS");
@ -1056,16 +1106,28 @@ USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, ui
#if DEBUG_TRANSFER #if DEBUG_TRANSFER
if (write) { if (write) {
USB_DBG_TRANSFER("%s WRITE buffer", type_str); USB_DBG_TRANSFER("%s WRITE buffer", type_str);
for (int i = 0; i < ep->getLengthTransferred(); i++) for (int i = 0; i < ep->getLengthTransferred(); i++) {
printf("%02X ", buf[i]); printf("%02X ", buf[i]);
}
printf("\r\n\r\n"); printf("\r\n\r\n");
} }
#endif #endif
res = addTransfer(ep, buf, len); res = addTransfer(ep, buf, len);
if ((blocking)&& (res == USB_TYPE_PROCESSING)) { 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(); ep->ep_queue.get();
#endif
res = ep->getState(); res = ep->getState();
USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep); USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep);
@ -1082,11 +1144,13 @@ USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, ui
} }
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); 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); return controlTransfer(dev, requestType, request, value, index, buf, len, true);
} }
@ -1112,15 +1176,30 @@ USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType,
#if DEBUG_TRANSFER #if DEBUG_TRANSFER
USB_DBG_TRANSFER("SETUP PACKET: "); USB_DBG_TRANSFER("SETUP PACKET: ");
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++) {
printf("%01X ", setupPacket[i]); printf("%01X ", setupPacket[i]);
}
printf("\r\n"); printf("\r\n");
#endif #endif
control->setNextToken(TD_SETUP); control->setNextToken(TD_SETUP);
res = addTransfer(control, (uint8_t*)setupPacket, 8); 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(); res = control->getState();
USB_DBG_TRANSFER("CONTROL setup stage %s", control->getStateString()); USB_DBG_TRANSFER("CONTROL setup stage %s", control->getStateString());
@ -1134,20 +1213,36 @@ USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType,
control->setNextToken(token); control->setNextToken(token);
res = addTransfer(control, (uint8_t *)buf, length_transfer); 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(); res = control->getState();
#if DEBUG_TRANSFER #if DEBUG_TRANSFER
USB_DBG_TRANSFER("CONTROL %s stage %s", (write) ? "WRITE" : "READ", control->getStateString()); USB_DBG_TRANSFER("CONTROL %s stage %s", (write) ? "WRITE" : "READ", control->getStateString());
if (write) { if (write) {
USB_DBG_TRANSFER("CONTROL WRITE buffer"); USB_DBG_TRANSFER("CONTROL WRITE buffer");
for (int i = 0; i < control->getLengthTransferred(); i++) for (int i = 0; i < control->getLengthTransferred(); i++) {
printf("%02X ", buf[i]); printf("%02X ", buf[i]);
}
printf("\r\n\r\n"); printf("\r\n\r\n");
} else { } else {
USB_DBG_TRANSFER("CONTROL READ SUCCESS [%d bytes transferred]", control->getLengthTransferred()); USB_DBG_TRANSFER("CONTROL READ SUCCESS [%d bytes transferred]", control->getLengthTransferred());
for (int i = 0; i < control->getLengthTransferred(); i++) for (int i = 0; i < control->getLengthTransferred(); i++) {
printf("%02X ", buf[i]); printf("%02X ", buf[i]);
}
printf("\r\n\r\n"); printf("\r\n\r\n");
} }
#endif #endif
@ -1160,14 +1255,28 @@ USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType,
token = (write) ? TD_IN : TD_OUT; token = (write) ? TD_IN : TD_OUT;
control->setNextToken(token); control->setNextToken(token);
res = addTransfer(control, NULL, 0); res = addTransfer(control, NULL, 0);
if (res == USB_TYPE_PROCESSING)
if (res == USB_TYPE_PROCESSING) control->ep_queue.get(); #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(); res = control->getState();
USB_DBG_TRANSFER("CONTROL ack stage %s", control->getStateString()); USB_DBG_TRANSFER("CONTROL ack stage %s", control->getStateString());
if (res != USB_TYPE_IDLE) if (res != USB_TYPE_IDLE) {
return res; return res;
}
return USB_TYPE_OK; return USB_TYPE_OK;
} }

View File

@ -22,17 +22,17 @@
* to the usb host * to the usb host
*/ */
/* hub + 2 devices */ /* hub + 2 devices */
#define MAX_DEVICE_CONNECTED 3 #define MAX_DEVICE_CONNECTED 5
/* /*
* Maximum of Hub connected to the usb host * 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 * Maximum number of ports on a USB hub
*/ */
#define MAX_HUB_PORT 2 #define MAX_HUB_PORT 4
/* /*
* Enable USBHostMSD * Enable USBHostMSD

View File

@ -117,6 +117,8 @@ enum ENDPOINT_TYPE {
#else #else
#define TD_TIMEOUT_CTRL 100
#define TD_TIMEOUT 2000
#define TD_SETUP (uint32_t)(0) // Direction of Setup Packet #define TD_SETUP (uint32_t)(0) // Direction of Setup Packet
#define TD_IN (uint32_t)(0x00100000) // Direction In #define TD_IN (uint32_t)(0x00100000) // Direction In
#define TD_OUT (uint32_t)(0x00080000) // Direction Out #define TD_OUT (uint32_t)(0x00080000) // Direction Out
@ -157,6 +159,8 @@ typedef struct hcTd {
__IO hcTd * nextTD; // Physical pointer to next Transfer Descriptor __IO hcTd * nextTD; // Physical pointer to next Transfer Descriptor
__IO uint32_t size; // size of buffer __IO uint32_t size; // size of buffer
void * ep; // ep address where a td is linked in void * ep; // ep address where a td is linked in
__IO uint32_t retry;
__IO uint32_t setup;
} PACKED HCTD; } PACKED HCTD;
// ----------- HostController EndPoint Descriptor ------------- // ----------- HostController EndPoint Descriptor -------------
typedef struct hcEd { typedef struct hcEd {

View File

@ -19,7 +19,8 @@
#if USBHOST_KEYBOARD #if USBHOST_KEYBOARD
static uint8_t keymap[4][0x39] = { static uint8_t keymap[4][0x39] = {
{ 0, 0, 0, 0, 'a', 'b' /*0x05*/, {
0, 0, 0, 0, 'a', 'b' /*0x05*/,
'c', 'd', 'e', 'f', 'g' /*0x0a*/, 'c', 'd', 'e', 'f', 'g' /*0x0a*/,
'h', 'i', 'j', 'k', 'l'/*0x0f*/, 'h', 'i', 'j', 'k', 'l'/*0x0f*/,
'm', 'n', 'o', 'p', 'q'/*0x14*/, 'm', 'n', 'o', 'p', 'q'/*0x14*/,
@ -30,10 +31,12 @@ static uint8_t keymap[4][0x39] = {
0x1B /*escape*/, 0x08 /*backspace*/, 0x09/*tab*/, 0x20/*space*/, '-', /*0x2d*/ 0x1B /*escape*/, 0x08 /*backspace*/, 0x09/*tab*/, 0x20/*space*/, '-', /*0x2d*/
'=', '[', ']', '\\', '#', /*0x32*/ '=', '[', ']', '\\', '#', /*0x32*/
';', '\'', 0, ',', '.', /*0x37*/ ';', '\'', 0, ',', '.', /*0x37*/
'/'}, '/'
},
/* CTRL MODIFIER */ /* CTRL MODIFIER */
{ 0, 0, 0, 0, 0, 0 /*0x05*/, {
0, 0, 0, 0, 0, 0 /*0x05*/,
0, 0, 0, 0, 0 /*0x0a*/, 0, 0, 0, 0, 0 /*0x0a*/,
0, 0, 0, 0, 0/*0x0f*/, 0, 0, 0, 0, 0/*0x0f*/,
0, 0, 0, 0, 0/*0x14*/, 0, 0, 0, 0, 0/*0x14*/,
@ -44,10 +47,12 @@ static uint8_t keymap[4][0x39] = {
0, 0, 0, 0, 0, /*0x2d*/ 0, 0, 0, 0, 0, /*0x2d*/
0, 0, 0, 0, 0, /*0x32*/ 0, 0, 0, 0, 0, /*0x32*/
0, 0, 0, 0, 0, /*0x37*/ 0, 0, 0, 0, 0, /*0x37*/
0}, 0
},
/* SHIFT MODIFIER */ /* SHIFT MODIFIER */
{ 0, 0, 0, 0, 'A', 'B' /*0x05*/, {
0, 0, 0, 0, 'A', 'B' /*0x05*/,
'C', 'D', 'E', 'F', 'G' /*0x0a*/, 'C', 'D', 'E', 'F', 'G' /*0x0a*/,
'H', 'I', 'J', 'K', 'L'/*0x0f*/, 'H', 'I', 'J', 'K', 'L'/*0x0f*/,
'M', 'N', 'O', 'P', 'Q'/*0x14*/, 'M', 'N', 'O', 'P', 'Q'/*0x14*/,
@ -58,10 +63,12 @@ static uint8_t keymap[4][0x39] = {
0, 0, 0, 0, 0, /*0x2d*/ 0, 0, 0, 0, 0, /*0x2d*/
'+', '{', '}', '|', '~', /*0x32*/ '+', '{', '}', '|', '~', /*0x32*/
':', '"', 0, '<', '>', /*0x37*/ ':', '"', 0, '<', '>', /*0x37*/
'?'}, '?'
},
/* ALT MODIFIER */ /* ALT MODIFIER */
{ 0, 0, 0, 0, 0, 0 /*0x05*/, {
0, 0, 0, 0, 0, 0 /*0x05*/,
0, 0, 0, 0, 0 /*0x0a*/, 0, 0, 0, 0, 0 /*0x0a*/,
0, 0, 0, 0, 0/*0x0f*/, 0, 0, 0, 0, 0/*0x0f*/,
0, 0, 0, 0, 0/*0x14*/, 0, 0, 0, 0, 0/*0x14*/,
@ -72,18 +79,21 @@ static uint8_t keymap[4][0x39] = {
0, 0, 0, 0, 0, /*0x2d*/ 0, 0, 0, 0, 0, /*0x2d*/
0, 0, 0, 0, 0, /*0x32*/ 0, 0, 0, 0, 0, /*0x32*/
0, 0, 0, 0, 0, /*0x37*/ 0, 0, 0, 0, 0, /*0x37*/
0} 0
}
}; };
USBHostKeyboard::USBHostKeyboard() { USBHostKeyboard::USBHostKeyboard()
{
host = USBHost::getHostInst(); host = USBHost::getHostInst();
init(); init();
} }
void USBHostKeyboard::init() { void USBHostKeyboard::init()
{
dev = NULL; dev = NULL;
int_in = NULL; int_in = NULL;
report_id = 0; report_id = 0;
@ -94,12 +104,14 @@ void USBHostKeyboard::init() {
keyboard_device_found = false; keyboard_device_found = false;
} }
bool USBHostKeyboard::connected() { bool USBHostKeyboard::connected()
{
return dev_connected; return dev_connected;
} }
bool USBHostKeyboard::connect() { bool USBHostKeyboard::connect()
{
if (dev_connected) { if (dev_connected) {
return true; return true;
@ -108,20 +120,29 @@ bool USBHostKeyboard::connect() {
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) { if ((dev = host->getDevice(i)) != NULL) {
if (host->enumerate(dev, this)) if (host->enumerate(dev, this)) {
break; break;
}
if (keyboard_device_found) { if (keyboard_device_found) {
{
/* 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(keyboard_intf, INTERRUPT_ENDPOINT, IN); int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN);
if (!int_in) if (!int_in) {
break; break;
}
USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf); 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); dev->setName("Keyboard", keyboard_intf);
host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init); host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init);
int_in->attach(this, &USBHostKeyboard::rxHandler); int_in->attach(this, &USBHostKeyboard::rxHandler);
}
host->interruptRead(dev, int_in, report, int_in->getSize(), false); host->interruptRead(dev, int_in, report, int_in->getSize(), false);
dev_connected = true; dev_connected = true;
@ -133,7 +154,8 @@ bool USBHostKeyboard::connect() {
return false; return false;
} }
void USBHostKeyboard::rxHandler() { void USBHostKeyboard::rxHandler()
{
int len = int_in->getLengthTransferred(); int len = int_in->getLengthTransferred();
int index = (len == 9) ? 1 : 0; int index = (len == 9) ? 1 : 0;
int len_listen = int_in->getSize(); int len_listen = int_in->getSize();
@ -149,8 +171,9 @@ void USBHostKeyboard::rxHandler() {
(*onKeyCode)(report[index + 2], modifier); (*onKeyCode)(report[index + 2], modifier);
} }
} }
if (dev && int_in) if (dev && int_in) {
host->interruptRead(dev, int_in, report, len_listen, false); host->interruptRead(dev, int_in, report, len_listen, false);
}
} }
/*virtual*/ void USBHostKeyboard::setVidPid(uint16_t vid, uint16_t pid) /*virtual*/ void USBHostKeyboard::setVidPid(uint16_t vid, uint16_t pid)

View File

@ -26,7 +26,8 @@
/** /**
* A class to communicate a USB keyboard * A class to communicate a USB keyboard
*/ */
class USBHostKeyboard : public IUSBEnumerator { class USBHostKeyboard : public IUSBEnumerator
{
public: public:
/** /**
@ -53,7 +54,8 @@ public:
* *
* @param ptr function pointer * @param ptr function pointer
*/ */
inline void attach(void (*ptr)(uint8_t key)) { inline void attach(void (*ptr)(uint8_t key))
{
if (ptr != NULL) { if (ptr != NULL) {
onKey = ptr; onKey = ptr;
} }
@ -64,7 +66,8 @@ public:
* *
* @param ptr function pointer * @param ptr function pointer
*/ */
inline void attach(void (*ptr)(uint8_t keyCode, uint8_t modifier)) { inline void attach(void (*ptr)(uint8_t keyCode, uint8_t modifier))
{
if (ptr != NULL) { if (ptr != NULL) {
onKeyCode = ptr; onKeyCode = ptr;
} }

View File

@ -18,12 +18,14 @@
#if USBHOST_MOUSE #if USBHOST_MOUSE
USBHostMouse::USBHostMouse() { USBHostMouse::USBHostMouse()
{
host = USBHost::getHostInst(); host = USBHost::getHostInst();
init(); init();
} }
void USBHostMouse::init() { void USBHostMouse::init()
{
dev = NULL; dev = NULL;
int_in = NULL; int_in = NULL;
onUpdate = NULL; onUpdate = NULL;
@ -42,11 +44,13 @@ void USBHostMouse::init() {
z = 0; z = 0;
} }
bool USBHostMouse::connected() { bool USBHostMouse::connected()
{
return dev_connected; return dev_connected;
} }
bool USBHostMouse::connect() { bool USBHostMouse::connect()
{
int len_listen; int len_listen;
if (dev_connected) { if (dev_connected) {
@ -56,14 +60,19 @@ bool USBHostMouse::connect() {
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) { if ((dev = host->getDevice(i)) != NULL) {
if(host->enumerate(dev, this)) if(host->enumerate(dev, this)) {
break; break;
}
if (mouse_device_found) { if (mouse_device_found) {
{
/* 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); int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN);
if (!int_in) if (!int_in) {
break; break;
}
USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf); 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); dev->setName("Mouse", mouse_intf);
@ -74,9 +83,15 @@ bool USBHostMouse::connect() {
if (len_listen > sizeof(report)) { if (len_listen > sizeof(report)) {
len_listen = sizeof(report); len_listen = sizeof(report);
} }
host->interruptRead(dev, int_in, report, len_listen, false); }
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; dev_connected = true;
}
if (ret == USB_TYPE_FREE) {
dev_connected = false;
}
return true; return true;
} }
} }
@ -85,8 +100,10 @@ bool USBHostMouse::connect() {
return false; return false;
} }
void USBHostMouse::rxHandler() { void USBHostMouse::rxHandler()
int len_listen = int_in->getSize(); {
int len_listen = int_in->getLengthTransferred();
if (len_listen !=0) {
if (onUpdate) { if (onUpdate) {
(*onUpdate)(report[0] & 0x07, report[1], report[2], report[3]); (*onUpdate)(report[0] & 0x07, report[1], report[2], report[3]);
@ -113,13 +130,17 @@ void USBHostMouse::rxHandler() {
x = report[1]; x = report[1];
y = report[2]; y = report[2];
z = report[3]; z = report[3];
}
/* set again the maximum value */
len_listen = int_in->getSize();
if (len_listen > sizeof(report)) { if (len_listen > sizeof(report)) {
len_listen = sizeof(report); len_listen = sizeof(report);
} }
if (dev) if (dev) {
host->interruptRead(dev, int_in, report, len_listen, false); host->interruptRead(dev, int_in, report, len_listen, false);
}
} }
/*virtual*/ void USBHostMouse::setVidPid(uint16_t vid, uint16_t pid) /*virtual*/ void USBHostMouse::setVidPid(uint16_t vid, uint16_t pid)

View File

@ -26,7 +26,8 @@
/** /**
* A class to communicate a USB mouse * A class to communicate a USB mouse
*/ */
class USBHostMouse : public IUSBEnumerator { class USBHostMouse : public IUSBEnumerator
{
public: public:
/** /**
@ -53,7 +54,8 @@ public:
* *
* @param ptr function pointer * @param ptr function pointer
*/ */
inline void attachEvent(void (*ptr)(uint8_t buttons, int8_t x, int8_t y, int8_t z)) { inline void attachEvent(void (*ptr)(uint8_t buttons, int8_t x, int8_t y, int8_t z))
{
if (ptr != NULL) { if (ptr != NULL) {
onUpdate = ptr; onUpdate = ptr;
} }
@ -64,7 +66,8 @@ public:
* *
* @param ptr function pointer * @param ptr function pointer
*/ */
inline void attachButtonEvent(void (*ptr)(uint8_t buttons)) { inline void attachButtonEvent(void (*ptr)(uint8_t buttons))
{
if (ptr != NULL) { if (ptr != NULL) {
onButtonUpdate = ptr; onButtonUpdate = ptr;
} }
@ -75,7 +78,8 @@ public:
* *
* @param ptr function pointer * @param ptr function pointer
*/ */
inline void attachXEvent(void (*ptr)(int8_t x)) { inline void attachXEvent(void (*ptr)(int8_t x))
{
if (ptr != NULL) { if (ptr != NULL) {
onXUpdate = ptr; onXUpdate = ptr;
} }
@ -86,7 +90,8 @@ public:
* *
* @param ptr function pointer * @param ptr function pointer
*/ */
inline void attachYEvent(void (*ptr)(int8_t y)) { inline void attachYEvent(void (*ptr)(int8_t y))
{
if (ptr != NULL) { if (ptr != NULL) {
onYUpdate = ptr; onYUpdate = ptr;
} }
@ -97,7 +102,8 @@ public:
* *
* @param ptr function pointer * @param ptr function pointer
*/ */
inline void attachZEvent(void (*ptr)(int8_t z)) { inline void attachZEvent(void (*ptr)(int8_t z))
{
if (ptr != NULL) { if (ptr != NULL) {
onZUpdate = ptr; onZUpdate = ptr;
} }
@ -113,8 +119,7 @@ private:
USBHost * host; USBHost * host;
USBDeviceConnected * dev; USBDeviceConnected * dev;
USBEndpoint * int_in; USBEndpoint * int_in;
uint8_t report[4]; uint8_t report[64];
bool dev_connected; bool dev_connected;
bool mouse_device_found; bool mouse_device_found;
int mouse_intf; int mouse_intf;

View File

@ -50,12 +50,14 @@
#define C_PORT_OVER_CURRENT (1 << 19) #define C_PORT_OVER_CURRENT (1 << 19)
#define C_PORT_RESET (1 << 20) #define C_PORT_RESET (1 << 20)
USBHostHub::USBHostHub() { USBHostHub::USBHostHub()
{
host = NULL; host = NULL;
init(); init();
} }
void USBHostHub::init() { void USBHostHub::init()
{
dev_connected = false; dev_connected = false;
dev = NULL; dev = NULL;
int_in = NULL; int_in = NULL;
@ -70,7 +72,8 @@ void USBHostHub::init() {
} }
} }
void USBHostHub::setHost(USBHost * host_) { void USBHostHub::setHost(USBHost * host_)
{
host = host_; host = host_;
} }
@ -129,7 +132,8 @@ bool USBHostHub::connect(USBDeviceConnected * dev)
return false; return false;
} }
void USBHostHub::disconnect() { void USBHostHub::disconnect()
{
init(); init();
} }
@ -161,15 +165,18 @@ void USBHostHub::disconnect() {
return false; return false;
} }
void USBHostHub::deviceConnected(USBDeviceConnected * dev) { void USBHostHub::deviceConnected(USBDeviceConnected * dev)
{
device_children[dev->getPort() - 1] = dev; device_children[dev->getPort() - 1] = dev;
} }
void USBHostHub::deviceDisconnected(USBDeviceConnected * dev) { void USBHostHub::deviceDisconnected(USBDeviceConnected * dev)
{
device_children[dev->getPort() - 1] = NULL; device_children[dev->getPort() - 1] = NULL;
} }
void USBHostHub::hubDisconnected() { void USBHostHub::hubDisconnected()
{
for (uint8_t i = 0; i < MAX_HUB_PORT; i++) { for (uint8_t i = 0; i < MAX_HUB_PORT; i++) {
if (device_children[i] != NULL) { if (device_children[i] != NULL) {
host->freeDevice(device_children[i]); host->freeDevice(device_children[i]);
@ -177,10 +184,11 @@ void USBHostHub::hubDisconnected() {
} }
} }
void USBHostHub::rxHandler() { void USBHostHub::rxHandler()
{
uint32_t status; uint32_t status;
if (int_in) { 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++) { for (int port = 1; port <= nb_port; port++) {
status = getPortStatus(port); status = getPortStatus(port);
USB_DBG("[hub handler hub: %d] status port %d [hub: %p]: 0x%X", dev->getHub(), port, dev, status); USB_DBG("[hub handler hub: %d] status port %d [hub: %p]: 0x%X", dev->getHub(), port, dev, status);
@ -217,7 +225,8 @@ void USBHostHub::rxHandler() {
} }
} }
void USBHostHub::portReset(uint8_t port) { void USBHostHub::portReset(uint8_t port)
{
// reset port // reset port
uint32_t status; uint32_t status;
USB_DBG("reset port %d on hub: %p [this: %p]", port, dev, this) USB_DBG("reset port %d on hub: %p [this: %p]", port, dev, this)
@ -228,10 +237,12 @@ void USBHostHub::portReset(uint8_t port) {
while(1) { while(1) {
status = getPortStatus(port); status = getPortStatus(port);
/* disconnection since reset request */ /* disconnection since reset request */
if (!(status & PORT_CONNECTION)) if (!(status & PORT_CONNECTION)) {
break; break;
if (status & (PORT_ENABLE | PORT_RESET)) }
if (status & (PORT_ENABLE | PORT_RESET)) {
break; break;
}
if (status & PORT_OVER_CURRENT) { if (status & PORT_OVER_CURRENT) {
USB_ERR("OVER CURRENT DETECTED\r\n"); USB_ERR("OVER CURRENT DETECTED\r\n");
clearPortFeature(PORT_OVER_CURRENT, port); clearPortFeature(PORT_OVER_CURRENT, port);
@ -242,7 +253,8 @@ void USBHostHub::portReset(uint8_t port) {
} }
} }
void USBHostHub::setPortFeature(uint32_t feature, uint8_t port) { void USBHostHub::setPortFeature(uint32_t feature, uint8_t port)
{
host->controlWrite( dev, host->controlWrite( dev,
USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT, USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
SET_FEATURE, SET_FEATURE,
@ -252,7 +264,8 @@ void USBHostHub::setPortFeature(uint32_t feature, uint8_t port) {
0); 0);
} }
void USBHostHub::clearPortFeature(uint32_t feature, uint8_t port) { void USBHostHub::clearPortFeature(uint32_t feature, uint8_t port)
{
host->controlWrite( dev, host->controlWrite( dev,
USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT, USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
CLEAR_FEATURE, CLEAR_FEATURE,
@ -262,7 +275,8 @@ void USBHostHub::clearPortFeature(uint32_t feature, uint8_t port) {
0); 0);
} }
uint32_t USBHostHub::getPortStatus(uint8_t port) { uint32_t USBHostHub::getPortStatus(uint8_t port)
{
uint32_t st; uint32_t st;
host->controlRead( dev, host->controlRead( dev,
USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT, USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,

View File

@ -31,7 +31,8 @@ class USBEndpoint;
/** /**
* A class to use a USB Hub * A class to use a USB Hub
*/ */
class USBHostHub : public IUSBEnumerator { class USBHostHub : public IUSBEnumerator
{
public: public:
/** /**
* Constructor * Constructor

View File

@ -930,11 +930,15 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
/* re-activate the channel */ /* re-activate the channel */
tmpreg = USBx_HC(chnum)->HCCHAR; tmpreg = USBx_HC(chnum)->HCCHAR;
tmpreg &= ~USB_OTG_HCCHAR_CHDIS; tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
if ( hhcd->hc[chnum].urb_state != URB_ERROR) {
tmpreg |= USB_OTG_HCCHAR_CHENA; tmpreg |= USB_OTG_HCCHAR_CHENA;
USBx_HC(chnum)->HCCHAR = tmpreg;
reactivate = 1; reactivate = 1;
} }
USBx_HC(chnum)->HCCHAR = tmpreg;
}
__HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
if (hhcd->hc[chnum].state == 0) reactivate = 1;
if (reactivate == 0) HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); if (reactivate == 0) HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
} }

View File

@ -931,10 +931,14 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
/* re-activate the channel */ /* re-activate the channel */
tmpreg = USBx_HC(chnum)->HCCHAR; tmpreg = USBx_HC(chnum)->HCCHAR;
tmpreg &= ~USB_OTG_HCCHAR_CHDIS; tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
if ( hhcd->hc[chnum].urb_state != URB_ERROR) {
tmpreg |= USB_OTG_HCCHAR_CHENA; tmpreg |= USB_OTG_HCCHAR_CHENA;
USBx_HC(chnum)->HCCHAR = tmpreg;
reactivate = 1; reactivate = 1;
} }
USBx_HC(chnum)->HCCHAR = tmpreg;
}
if (hhcd->hc[chnum].state == 0) reactivate = 1;
__HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
if (reactivate == 0) HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); if (reactivate == 0) HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
} }

View File

@ -932,11 +932,14 @@ static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
/* re-activate the channel */ /* re-activate the channel */
tmpreg = USBx_HC(chnum)->HCCHAR; tmpreg = USBx_HC(chnum)->HCCHAR;
tmpreg &= ~USB_OTG_HCCHAR_CHDIS; tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
if ( hhcd->hc[chnum].urb_state != URB_ERROR) {
tmpreg |= USB_OTG_HCCHAR_CHENA; tmpreg |= USB_OTG_HCCHAR_CHENA;
USBx_HC(chnum)->HCCHAR = tmpreg;
reactivate = 1; reactivate = 1;
} }
USBx_HC(chnum)->HCCHAR = tmpreg;
}
__HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
if (hhcd->hc[chnum].state == 0) reactivate = 1;
if (reactivate == 0 )HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); if (reactivate == 0 )HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
} }

View File

@ -939,11 +939,14 @@ static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
/* re-activate the channel */ /* re-activate the channel */
tmpreg = USBx_HC(chnum)->HCCHAR; tmpreg = USBx_HC(chnum)->HCCHAR;
tmpreg &= ~USB_OTG_HCCHAR_CHDIS; tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
if ( hhcd->hc[chnum].urb_state != URB_ERROR) {
tmpreg |= USB_OTG_HCCHAR_CHENA; tmpreg |= USB_OTG_HCCHAR_CHENA;
USBx_HC(chnum)->HCCHAR = tmpreg;
reactivate = 1; reactivate = 1;
} }
USBx_HC(chnum)->HCCHAR = tmpreg;
}
__HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
if (hhcd->hc[chnum].state == 0) reactivate = 1;
if (reactivate == 0) HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); if (reactivate == 0) HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
} }