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"
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 @@ void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir
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,16 @@ void USBEndpoint::setSize(uint32_t size)
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 +89,43 @@ void USBEndpoint::setSpeed(uint8_t speed)
void USBEndpoint::setState(uint8_t st) {
if (st > 18)
void USBEndpoint::setState(USB_TYPE st)
{
/* modify this state is possible only with a plug */
if (state == USB_TYPE_FREE) {
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);
}
}
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 +133,38 @@ USB_TYPE USBEndpoint::queueTransfer()
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;

View File

@ -26,52 +26,44 @@ void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
{
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,105 +71,158 @@ void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd,uint8_t chnum,
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;
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) {
/* 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;
}
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) {
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) {
return true;
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;
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;
@ -188,7 +233,8 @@ volatile uint8_t * USBHALHost::getED() {
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] ) {
@ -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;
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

View File

@ -33,6 +33,9 @@ public:
* Constructor
*/
USBEndpoint() {
#ifdef USBHOST_OTHER
speed = false;
#endif
state = USB_TYPE_FREE;
nextEp = NULL;
};
@ -111,7 +114,11 @@ public:
// 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; };

View File

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

View File

@ -46,7 +46,8 @@ USBHost * USBHost::instHost = NULL;
* - 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,130 @@ void USBHost::usb_process() {
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++) {
if (!controlEndpointAllocated) {
control = newEndpoint(CONTROL_ENDPOINT, OUT, 0x08, 0x00);
addEndpoint(NULL, 0, (USBEndpoint*)control);
controlEndpointAllocated = true;
}
resetDevice(&devices[i]);
#if MAX_HUB_NB
if (usb_msg->hub_parent) {
devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent));
}
#endif
// set size of control endpoint
devices[i].setSizeControlEndpoint(8);
for (j = 0; j < timeout_set_addr; j++) {
devices[i].activeAddress(false);
resetDevice(&devices[i]);
// 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);
// set size of control endpoint
devices[i].setSizeControlEndpoint(8);
if (res != USB_TYPE_OK) {
USB_ERR("usb_thread could not read dev descr");
continue;
}
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]);
// try to read again the device descriptor to check if the device
// answers to its new address
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) {
break;
}
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());
Thread::wait(100);
}
// try to read again the device descriptor to check if the device
// answers to its new address
res = getDeviceDescriptor(&devices[i], buf, 8);
USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port);
if (res == USB_TYPE_OK) {
break;
}
#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;
}
}
Thread::wait(100);
}
if (k == MAX_HUB_NB) {
USB_ERR("Too many hubs connected!!\r\n");
too_many_hub = true;
}
}
USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port);
if (usb_msg->hub_parent)
((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]);
#endif
#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 ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) {
deviceInUse[i] = true;
}
if (k == MAX_HUB_NB) {
USB_ERR("Too many hubs connected!!\r\n");
too_many_hub = 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 +212,28 @@ void USBHost::usb_process() {
// 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);
@ -224,8 +251,9 @@ void USBHost::usb_process() {
if (ep->getDir() == IN) {
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());
for (int i = 0; i < ep->getLengthTransferred(); i++)
for (int i = 0; i < ep->getLengthTransferred(); i++) {
printf("%02X ", buf_transfer[i]);
}
printf("\r\n\r\n");
}
#endif
@ -236,6 +264,12 @@ void USBHost::usb_process() {
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();
}
}
}
@ -266,8 +300,9 @@ USBHost::USBHost() : usbThread(osPriorityNormal, USB_THREAD_STACK)
devices[i].setAddress(i + 1);
deviceReset[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;
}
}
#if MAX_HUB_NB
@ -282,20 +317,21 @@ USBHost::USBHost() : usbThread(osPriorityNormal, USB_THREAD_STACK)
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)
{
uint8_t state;
if(addr == 0)
if(addr == 0) {
return;
}
volatile HCTD* tdList = NULL;
@ -315,20 +351,23 @@ void USBHost::transferCompleted(volatile uint32_t addr)
#ifdef USBHOST_OTHER
state = ((HCTD *)td)->state;
if (state == USB_TYPE_IDLE)
if (state == USB_TYPE_IDLE) {
ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
}
#else
if (((HCTD *)td)->control >> 28) {
state = ((HCTD *)td)->control >> 28;
} else {
if (td->currBufPtr)
if (td->currBufPtr) {
ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
}
state = 16 /*USB_TYPE_IDLE*/;
}
#endif
if (state == USB_TYPE_IDLE)
if (state == USB_TYPE_IDLE) {
ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
}
ep->unqueueTransfer(td);
@ -340,7 +379,7 @@ void USBHost::transferCompleted(volatile uint32_t addr)
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);
}
}
@ -365,8 +404,9 @@ USBHost * USBHost::getHostInst()
// be sure that the new device connected is not already connected...
int idx = findDevice(hub, port, hub_parent);
if (idx != -1) {
if (deviceInited[idx])
if (deviceInited[idx]) {
return;
}
}
message_t * usb_msg = mail_usb_event.alloc();
@ -387,8 +427,9 @@ USBHost * USBHost::getHostInst()
// be sure that the device disconnected is connected...
int idx = findDevice(hub, port, hub_parent);
if (idx != -1) {
if (!deviceInUse[idx])
if (!deviceInUse[idx]) {
return;
}
} else {
return;
}
@ -422,8 +463,9 @@ void USBHost::freeDevice(USBDeviceConnected * dev)
}
// notify hub parent that this device has been disconnected
if (dev->getHubParent())
if (dev->getHubParent()) {
dev->getHubParent()->deviceDisconnected(dev);
}
#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++) {
if (devices[i].getHub() == hub && devices[i].getPort() == port) {
if (hub_parent != NULL) {
if (hub_parent == devices[i].getHubParent())
if (hub_parent == devices[i].getHubParent()) {
return i;
}
} else {
return i;
}
@ -695,14 +738,14 @@ void USBHost::printList(ENDPOINT_TYPE type)
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 +763,7 @@ void USBHost::printList(ENDPOINT_TYPE type)
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 +771,7 @@ USB_TYPE USBHost::addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len)
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 +797,10 @@ USB_TYPE USBHost::addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len)
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,12 +813,13 @@ USB_TYPE USBHost::addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len)
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));
if (len_dev_descr)
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);
}
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 = MIN(max_len_buf, total_conf_descr_length);
if (len_conf_descr)
if (len_conf_descr) {
*len_conf_descr = total_conf_descr_length;
}
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,
USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE,
SET_ADDRESS,
@ -830,14 +876,17 @@ USB_TYPE USBHost::setConfiguration(USBDeviceConnected * dev, uint8_t conf)
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)
if (index == -1) {
return 0;
}
for (uint8_t i = 0; i < MAX_INTF; i++) {
if (deviceAttachedDriver[index][i])
if (deviceAttachedDriver[index][i]) {
cnt++;
}
}
return cnt;
}
@ -848,76 +897,76 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
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 +1065,8 @@ USB_TYPE USBHost::interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint
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");
@ -1056,16 +1106,28 @@ USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, ui
#if DEBUG_TRANSFER
if (write) {
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("\r\n\r\n");
}
#endif
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 +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);
}
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);
}
@ -1112,15 +1176,30 @@ USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType,
#if DEBUG_TRANSFER
USB_DBG_TRANSFER("SETUP PACKET: ");
for (int i = 0; i < 8; i++)
for (int i = 0; i < 8; i++) {
printf("%01X ", setupPacket[i]);
}
printf("\r\n");
#endif
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,20 +1213,36 @@ USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType,
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
USB_DBG_TRANSFER("CONTROL %s stage %s", (write) ? "WRITE" : "READ", control->getStateString());
if (write) {
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("\r\n\r\n");
} else {
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("\r\n\r\n");
}
#endif
@ -1160,14 +1255,28 @@ USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType,
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());
if (res != USB_TYPE_IDLE)
if (res != USB_TYPE_IDLE) {
return res;
}
return USB_TYPE_OK;
}

View File

@ -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

View File

@ -117,6 +117,8 @@ enum ENDPOINT_TYPE {
#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
@ -152,11 +154,13 @@ enum ENDPOINT_TYPE {
#if defined(USBHOST_OTHER)
typedef struct hcTd {
__IO uint32_t state;
__IO uint32_t state;
__IO uint8_t * currBufPtr; // Physical address of current buffer pointer
__IO hcTd * nextTD; // Physical pointer to next Transfer Descriptor
__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 {

View File

@ -19,71 +19,81 @@
#if USBHOST_KEYBOARD
static uint8_t keymap[4][0x39] = {
{ 0, 0, 0, 0, 'a', 'b' /*0x05*/,
'c', 'd', 'e', 'f', 'g' /*0x0a*/,
'h', 'i', 'j', 'k', 'l'/*0x0f*/,
'm', 'n', 'o', 'p', 'q'/*0x14*/,
'r', 's', 't', 'u', 'v'/*0x19*/,
'w', 'x', 'y', 'z', '1'/*0x1E*/,
'2', '3', '4', '5', '6'/*0x23*/,
'7', '8', '9', '0', 0x0A /*enter*/, /*0x28*/
0x1B /*escape*/, 0x08 /*backspace*/, 0x09/*tab*/, 0x20/*space*/, '-', /*0x2d*/
'=', '[', ']', '\\', '#', /*0x32*/
';', '\'', 0, ',', '.', /*0x37*/
'/'},
{
0, 0, 0, 0, 'a', 'b' /*0x05*/,
'c', 'd', 'e', 'f', 'g' /*0x0a*/,
'h', 'i', 'j', 'k', 'l'/*0x0f*/,
'm', 'n', 'o', 'p', 'q'/*0x14*/,
'r', 's', 't', 'u', 'v'/*0x19*/,
'w', 'x', 'y', 'z', '1'/*0x1E*/,
'2', '3', '4', '5', '6'/*0x23*/,
'7', '8', '9', '0', 0x0A /*enter*/, /*0x28*/
0x1B /*escape*/, 0x08 /*backspace*/, 0x09/*tab*/, 0x20/*space*/, '-', /*0x2d*/
'=', '[', ']', '\\', '#', /*0x32*/
';', '\'', 0, ',', '.', /*0x37*/
'/'
},
/* CTRL MODIFIER */
{ 0, 0, 0, 0, 0, 0 /*0x05*/,
0, 0, 0, 0, 0 /*0x0a*/,
0, 0, 0, 0, 0/*0x0f*/,
0, 0, 0, 0, 0/*0x14*/,
0, 0, 0, 0, 0/*0x19*/,
0, 0, 0, 0, 0/*0x1E*/,
0, 0, 0, 0, 0/*0x23*/,
0, 0, 0, 0, 0 /*enter*/, /*0x28*/
0, 0, 0, 0, 0, /*0x2d*/
0, 0, 0, 0, 0, /*0x32*/
0, 0, 0, 0, 0, /*0x37*/
0},
{
0, 0, 0, 0, 0, 0 /*0x05*/,
0, 0, 0, 0, 0 /*0x0a*/,
0, 0, 0, 0, 0/*0x0f*/,
0, 0, 0, 0, 0/*0x14*/,
0, 0, 0, 0, 0/*0x19*/,
0, 0, 0, 0, 0/*0x1E*/,
0, 0, 0, 0, 0/*0x23*/,
0, 0, 0, 0, 0 /*enter*/, /*0x28*/
0, 0, 0, 0, 0, /*0x2d*/
0, 0, 0, 0, 0, /*0x32*/
0, 0, 0, 0, 0, /*0x37*/
0
},
/* SHIFT MODIFIER */
{ 0, 0, 0, 0, 'A', 'B' /*0x05*/,
'C', 'D', 'E', 'F', 'G' /*0x0a*/,
'H', 'I', 'J', 'K', 'L'/*0x0f*/,
'M', 'N', 'O', 'P', 'Q'/*0x14*/,
'R', 'S', 'T', 'U', 'V'/*0x19*/,
'W', 'X', 'Y', 'Z', '!'/*0x1E*/,
'@', '#', '$', '%', '^'/*0x23*/,
'&', '*', '(', ')', 0, /*0x28*/
0, 0, 0, 0, 0, /*0x2d*/
'+', '{', '}', '|', '~', /*0x32*/
':', '"', 0, '<', '>', /*0x37*/
'?'},
{
0, 0, 0, 0, 'A', 'B' /*0x05*/,
'C', 'D', 'E', 'F', 'G' /*0x0a*/,
'H', 'I', 'J', 'K', 'L'/*0x0f*/,
'M', 'N', 'O', 'P', 'Q'/*0x14*/,
'R', 'S', 'T', 'U', 'V'/*0x19*/,
'W', 'X', 'Y', 'Z', '!'/*0x1E*/,
'@', '#', '$', '%', '^'/*0x23*/,
'&', '*', '(', ')', 0, /*0x28*/
0, 0, 0, 0, 0, /*0x2d*/
'+', '{', '}', '|', '~', /*0x32*/
':', '"', 0, '<', '>', /*0x37*/
'?'
},
/* ALT MODIFIER */
{ 0, 0, 0, 0, 0, 0 /*0x05*/,
0, 0, 0, 0, 0 /*0x0a*/,
0, 0, 0, 0, 0/*0x0f*/,
0, 0, 0, 0, 0/*0x14*/,
0, 0, 0, 0, 0/*0x19*/,
0, 0, 0, 0, 0/*0x1E*/,
0, 0, 0, 0, 0/*0x23*/,
0, 0, 0, 0, 0 /*enter*/, /*0x28*/
0, 0, 0, 0, 0, /*0x2d*/
0, 0, 0, 0, 0, /*0x32*/
0, 0, 0, 0, 0, /*0x37*/
0}
{
0, 0, 0, 0, 0, 0 /*0x05*/,
0, 0, 0, 0, 0 /*0x0a*/,
0, 0, 0, 0, 0/*0x0f*/,
0, 0, 0, 0, 0/*0x14*/,
0, 0, 0, 0, 0/*0x19*/,
0, 0, 0, 0, 0/*0x1E*/,
0, 0, 0, 0, 0/*0x23*/,
0, 0, 0, 0, 0 /*enter*/, /*0x28*/
0, 0, 0, 0, 0, /*0x2d*/
0, 0, 0, 0, 0, /*0x32*/
0, 0, 0, 0, 0, /*0x37*/
0
}
};
USBHostKeyboard::USBHostKeyboard() {
USBHostKeyboard::USBHostKeyboard()
{
host = USBHost::getHostInst();
init();
}
void USBHostKeyboard::init() {
void USBHostKeyboard::init()
{
dev = NULL;
int_in = NULL;
report_id = 0;
@ -94,12 +104,14 @@ void USBHostKeyboard::init() {
keyboard_device_found = false;
}
bool USBHostKeyboard::connected() {
bool USBHostKeyboard::connected()
{
return dev_connected;
}
bool USBHostKeyboard::connect() {
bool USBHostKeyboard::connect()
{
if (dev_connected) {
return true;
@ -108,20 +120,29 @@ bool USBHostKeyboard::connect() {
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) {
if (host->enumerate(dev, this))
if (host->enumerate(dev, this)) {
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;
@ -133,7 +154,8 @@ bool USBHostKeyboard::connect() {
return false;
}
void USBHostKeyboard::rxHandler() {
void USBHostKeyboard::rxHandler()
{
int len = int_in->getLengthTransferred();
int index = (len == 9) ? 1 : 0;
int len_listen = int_in->getSize();
@ -149,8 +171,9 @@ void USBHostKeyboard::rxHandler() {
(*onKeyCode)(report[index + 2], modifier);
}
}
if (dev && int_in)
if (dev && int_in) {
host->interruptRead(dev, int_in, report, len_listen, false);
}
}
/*virtual*/ void USBHostKeyboard::setVidPid(uint16_t vid, uint16_t pid)
@ -161,9 +184,9 @@ void USBHostKeyboard::rxHandler() {
/*virtual*/ bool USBHostKeyboard::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 ((keyboard_intf == -1) &&
(intf_class == HID_CLASS) &&
(intf_subclass == 0x01) &&
(intf_protocol == 0x01)) {
(intf_class == HID_CLASS) &&
(intf_subclass == 0x01) &&
(intf_protocol == 0x01)) {
keyboard_intf = intf_nb;
return true;
}

View File

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

View File

@ -18,12 +18,14 @@
#if USBHOST_MOUSE
USBHostMouse::USBHostMouse() {
USBHostMouse::USBHostMouse()
{
host = USBHost::getHostInst();
init();
}
void USBHostMouse::init() {
void USBHostMouse::init()
{
dev = NULL;
int_in = NULL;
onUpdate = NULL;
@ -42,11 +44,13 @@ void USBHostMouse::init() {
z = 0;
}
bool USBHostMouse::connected() {
bool USBHostMouse::connected()
{
return dev_connected;
}
bool USBHostMouse::connect() {
bool USBHostMouse::connect()
{
int len_listen;
if (dev_connected) {
@ -56,27 +60,38 @@ bool USBHostMouse::connect() {
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) {
if(host->enumerate(dev, this))
if(host->enumerate(dev, this)) {
break;
}
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);
if (!int_in) {
break;
}
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);
}
}
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;
}
host->interruptRead(dev, int_in, report, len_listen, false);
dev_connected = true;
return true;
}
}
@ -85,41 +100,47 @@ bool USBHostMouse::connect() {
return false;
}
void USBHostMouse::rxHandler() {
int len_listen = int_in->getSize();
void USBHostMouse::rxHandler()
{
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 (onXUpdate && (x != report[1])) {
(*onXUpdate)(report[1]);
}
if (onYUpdate && (y != report[2])) {
(*onYUpdate)(report[2]);
}
if (onZUpdate && (z != report[3])) {
(*onZUpdate)(report[3]);
}
// update mouse state
buttons = report[0] & 0x07;
x = report[1];
y = report[2];
z = report[3];
}
if (onButtonUpdate && (buttons != (report[0] & 0x07))) {
(*onButtonUpdate)(report[0] & 0x07);
}
if (onXUpdate && (x != report[1])) {
(*onXUpdate)(report[1]);
}
if (onYUpdate && (y != report[2])) {
(*onYUpdate)(report[2]);
}
if (onZUpdate && (z != report[3])) {
(*onZUpdate)(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);
}
if (dev)
if (dev) {
host->interruptRead(dev, int_in, report, len_listen, false);
}
}
/*virtual*/ void USBHostMouse::setVidPid(uint16_t vid, uint16_t pid)
@ -130,9 +151,9 @@ void USBHostMouse::rxHandler() {
/*virtual*/ bool USBHostMouse::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 ((mouse_intf == -1) &&
(intf_class == HID_CLASS) &&
(intf_subclass == 0x01) &&
(intf_protocol == 0x02)) {
(intf_class == HID_CLASS) &&
(intf_subclass == 0x01) &&
(intf_protocol == 0x02)) {
mouse_intf = intf_nb;
return true;
}

View File

@ -26,7 +26,8 @@
/**
* A class to communicate a USB mouse
*/
class USBHostMouse : public IUSBEnumerator {
class USBHostMouse : public IUSBEnumerator
{
public:
/**
@ -53,7 +54,8 @@ public:
*
* @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) {
onUpdate = ptr;
}
@ -64,7 +66,8 @@ public:
*
* @param ptr function pointer
*/
inline void attachButtonEvent(void (*ptr)(uint8_t buttons)) {
inline void attachButtonEvent(void (*ptr)(uint8_t buttons))
{
if (ptr != NULL) {
onButtonUpdate = ptr;
}
@ -75,7 +78,8 @@ public:
*
* @param ptr function pointer
*/
inline void attachXEvent(void (*ptr)(int8_t x)) {
inline void attachXEvent(void (*ptr)(int8_t x))
{
if (ptr != NULL) {
onXUpdate = ptr;
}
@ -86,7 +90,8 @@ public:
*
* @param ptr function pointer
*/
inline void attachYEvent(void (*ptr)(int8_t y)) {
inline void attachYEvent(void (*ptr)(int8_t y))
{
if (ptr != NULL) {
onYUpdate = ptr;
}
@ -97,7 +102,8 @@ public:
*
* @param ptr function pointer
*/
inline void attachZEvent(void (*ptr)(int8_t z)) {
inline void attachZEvent(void (*ptr)(int8_t z))
{
if (ptr != NULL) {
onZUpdate = ptr;
}
@ -113,8 +119,7 @@ private:
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;

View File

@ -50,12 +50,14 @@
#define C_PORT_OVER_CURRENT (1 << 19)
#define C_PORT_RESET (1 << 20)
USBHostHub::USBHostHub() {
USBHostHub::USBHostHub()
{
host = NULL;
init();
}
void USBHostHub::init() {
void USBHostHub::init()
{
dev_connected = false;
dev = NULL;
int_in = NULL;
@ -70,7 +72,8 @@ void USBHostHub::init() {
}
}
void USBHostHub::setHost(USBHost * host_) {
void USBHostHub::setHost(USBHost * host_)
{
host = host_;
}
@ -129,7 +132,8 @@ bool USBHostHub::connect(USBDeviceConnected * dev)
return false;
}
void USBHostHub::disconnect() {
void USBHostHub::disconnect()
{
init();
}
@ -141,9 +145,9 @@ void USBHostHub::disconnect() {
/*virtual*/ bool USBHostHub::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 ((hub_intf == -1) &&
(intf_class == HUB_CLASS) &&
(intf_subclass == 0) &&
(intf_protocol == 0)) {
(intf_class == HUB_CLASS) &&
(intf_subclass == 0) &&
(intf_protocol == 0)) {
hub_intf = intf_nb;
return true;
}
@ -161,15 +165,18 @@ void USBHostHub::disconnect() {
return false;
}
void USBHostHub::deviceConnected(USBDeviceConnected * dev) {
void USBHostHub::deviceConnected(USBDeviceConnected * dev)
{
device_children[dev->getPort() - 1] = dev;
}
void USBHostHub::deviceDisconnected(USBDeviceConnected * dev) {
void USBHostHub::deviceDisconnected(USBDeviceConnected * dev)
{
device_children[dev->getPort() - 1] = NULL;
}
void USBHostHub::hubDisconnected() {
void USBHostHub::hubDisconnected()
{
for (uint8_t i = 0; i < MAX_HUB_PORT; i++) {
if (device_children[i] != NULL) {
host->freeDevice(device_children[i]);
@ -177,10 +184,11 @@ void USBHostHub::hubDisconnected() {
}
}
void USBHostHub::rxHandler() {
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);
@ -217,7 +225,8 @@ void USBHostHub::rxHandler() {
}
}
void USBHostHub::portReset(uint8_t port) {
void USBHostHub::portReset(uint8_t port)
{
// reset port
uint32_t status;
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) {
status = getPortStatus(port);
/* disconnection since reset request */
if (!(status & PORT_CONNECTION))
if (!(status & PORT_CONNECTION)) {
break;
if (status & (PORT_ENABLE | PORT_RESET))
}
if (status & (PORT_ENABLE | PORT_RESET)) {
break;
}
if (status & PORT_OVER_CURRENT) {
USB_ERR("OVER CURRENT DETECTED\r\n");
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,
USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
SET_FEATURE,
@ -252,7 +264,8 @@ void USBHostHub::setPortFeature(uint32_t feature, uint8_t port) {
0);
}
void USBHostHub::clearPortFeature(uint32_t feature, uint8_t port) {
void USBHostHub::clearPortFeature(uint32_t feature, uint8_t port)
{
host->controlWrite( dev,
USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
CLEAR_FEATURE,
@ -262,7 +275,8 @@ void USBHostHub::clearPortFeature(uint32_t feature, uint8_t port) {
0);
}
uint32_t USBHostHub::getPortStatus(uint8_t port) {
uint32_t USBHostHub::getPortStatus(uint8_t port)
{
uint32_t st;
host->controlRead( dev,
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
*/
class USBHostHub : public IUSBEnumerator {
class USBHostHub : public IUSBEnumerator
{
public:
/**
* Constructor

View File

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

View File

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

View File

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

View File

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