spaces removal - USBHost

pull/339/head
0xc0170 2014-05-29 15:16:53 +02:00
parent 9017b27778
commit 081230ee9c
27 changed files with 621 additions and 372 deletions

View File

@ -50,10 +50,10 @@ void USBDeviceConnected::init() {
INTERFACE * USBDeviceConnected::getInterface(uint8_t index) {
if (index >= MAX_INTF)
return NULL;
if (intf[index].in_use)
return &intf[index];
return NULL;
}

View File

@ -33,7 +33,7 @@ typedef struct {
USBEndpoint * ep[MAX_ENDPOINT_PER_INTERFACE];
FunctionPointer detach;
char name[10];
} INTERFACE;
} INTERFACE;
/**
* USBDeviceConnected class
@ -157,7 +157,7 @@ public:
inline USBHostHub * getHubParent() { return hub_parent; };
inline uint8_t getNbIntf() { return nb_interf; };
inline const char * getName(uint8_t intf_nb) { return intf[intf_nb].name; };
// in case this device is a hub
USBHostHub * hub;

View File

@ -29,7 +29,7 @@ void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir
memcpy((HCTD**)td_list, td_list_, sizeof(HCTD*)*2); //TODO: Maybe should add a param for td_list size... at least a define
memset(td_list_[0], 0, sizeof(HCTD));
memset(td_list_[1], 0, sizeof(HCTD));
td_list[0]->ep = this;
td_list[1]->ep = this;
@ -52,7 +52,7 @@ void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir
td_current = td_list[0];
td_next = td_list[1];
intf_nb = 0;
state = USB_TYPE_IDLE;

View File

@ -136,9 +136,9 @@ public:
inline bool isSetup() { return setup; }
inline USBEndpoint * nextEndpoint() { return (USBEndpoint*)nextEp; };
inline uint8_t getIntfNb() { return intf_nb; };
USBDeviceConnected * dev;
Queue<uint8_t, 1> ep_queue;
private:
@ -163,7 +163,7 @@ private:
volatile HCTD * td_list[2];
volatile HCTD * td_current;
volatile HCTD * td_next;
uint8_t intf_nb;
};

View File

@ -57,7 +57,7 @@ USBHALHost::USBHALHost() {
void USBHALHost::init() {
NVIC_DisableIRQ(USB_IRQn);
//Cut power
LPC_SC->PCONP &= ~(1UL<<31);
wait_ms(100);
@ -98,7 +98,7 @@ void USBHALHost::init() {
// software reset
LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
// Write Fm Interval and Largest Data Packet Counter
LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL;
LPC_USB->HcPeriodicStart = FI * 90 / 100;
@ -109,7 +109,7 @@ void USBHALHost::init() {
LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC;
LPC_USB->HcHCCA = (uint32_t)(usb_hcca);
// Clear Interrrupt Status
LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus;
@ -249,9 +249,9 @@ void USBHALHost::freeTD(volatile uint8_t * td) {
void USBHALHost::resetRootHub() {
// Initiate port reset
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS;
while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS);
// ...and clear port reset signal
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
}
@ -266,11 +266,11 @@ void USBHALHost::_usbisr(void) {
void USBHALHost::UsbIrqhandler() {
if( LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable ) //Is there something to actually process?
{
uint32_t int_status = LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable;
// Root hub status change interrupt
if (int_status & OR_INTR_STATUS_RHSC) {
if (int_status & OR_INTR_STATUS_RHSC) {
if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) {
if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) {
// When DRWE is on, Connect Status Change
@ -278,27 +278,27 @@ void USBHALHost::UsbIrqhandler() {
} else {
//Root device connected
if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
// wait 150ms to avoid bounce
wait_ms(150);
//Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed
deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA);
}
deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA);
}
//Root device disconnected
else {
else {
if (!(int_status & OR_INTR_STATUS_WDH)) {
usb_hcca->DoneHead = 0;
}
// wait 200ms to avoid bounce
wait_ms(200);
deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE);
if (int_status & OR_INTR_STATUS_WDH) {
usb_hcca->DoneHead = 0;
LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH;

View File

@ -33,61 +33,61 @@ protected:
* init variables and memory where will be stored HCCA, ED and TD
*/
USBHALHost();
/**
* Initialize host controller. Enable USB interrupts. This part is not in the constructor because,
* Initialize host controller. Enable USB interrupts. This part is not in the constructor because,
* this function calls a virtual method if a device is already connected
*/
void init();
/**
* reset the root hub
*/
void resetRootHub();
/**
* return the value contained in the control HEAD ED register
*
* @returns address of the control Head ED
*/
uint32_t controlHeadED();
/**
* return the value contained in the bulk HEAD ED register
*
* @returns address of the bulk head ED
*/
uint32_t bulkHeadED();
/**
* return the value of the head interrupt ED contained in the HCCA
*
* @returns address of the head interrupt ED contained in the HCCA
*/
uint32_t interruptHeadED();
/**
* Update the head ED for control transfers
*/
void updateControlHeadED(uint32_t addr);
/**
* Update the head ED for bulk transfers
*/
void updateBulkHeadED(uint32_t addr);
/**
* Update the head ED for interrupt transfers
*/
void updateInterruptHeadED(uint32_t addr);
/**
* Enable List for the specified endpoint type
*
* @param type enable the list of ENDPOINT_TYPE type
*/
void enableList(ENDPOINT_TYPE type);
/**
* Disable List for the specified endpoint type
*
@ -104,7 +104,7 @@ protected:
* @param hub_parent reference to the hub where the device is connected (NULL if the hub parent is the root hub)
*/
virtual void deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent = NULL) = 0;
/**
* Virtual method called when a device has been disconnected
*
@ -114,35 +114,35 @@ protected:
* @param addr list of the TDs which have been completed to dequeue freed TDs
*/
virtual void deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr) = 0;
/**
* Virtual method called when a transfer has been completed
*
* @param addr list of the TDs which have been completed
*/
virtual void transferCompleted(volatile uint32_t addr) = 0;
/**
* Find a memory section for a new ED
*
* @returns the address of the new ED
*/
volatile uint8_t * getED();
/**
* Find a memory section for a new TD
*
* @returns the address of the new TD
*/
volatile uint8_t * getTD();
/**
* Release a previous memory section reserved for an ED
*
* @param ed address of the ED
*/
void freeED(volatile uint8_t * ed);
/**
* Release a previous memory section reserved for an TD
*
@ -161,7 +161,7 @@ private:
uint8_t volatile * usb_tdBuf; //4 bytes aligned
static USBHALHost * instHost;
bool volatile edBufAlloc[MAX_ENDPOINT];
bool volatile tdBufAlloc[MAX_TD];
};

View File

@ -0,0 +1,249 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined(TARGET_KL46Z)
#include "mbed.h"
#include "USBHALHost.h"
#include "dbg.h"
#define BD_OWN_MASK (1 << 7)
#define BD_DATA01_MASK (1 << 6)
#define BD_KEEP_MASK (1 << 5)
#define BD_NINC_MASK (1 << 4)
#define BD_DTS_MASK (1 << 3)
#define BD_STALL_MASK (1 << 2)
#define TX 1
#define RX 0
#define EP0_BDT_IDX(dir, odd) (((2 * dir) + (1 * odd)))
#define SETUP_TOKEN 0x0D
#define IN_TOKEN 0x09
#define OUT_TOKEN 0x01
/* buffer descriptor table */
__attribute__((__aligned__(512))) BDT bdt[64];
// for each endpt: 8 bytes
struct BDT {
uint8_t info; // BD[0:7]
uint8_t dummy; // RSVD: BD[8:15]
uint16_t byte_count; // BD[16:32]
uint32_t address; // Addr
};
USBHALHost * USBHALHost::instHost;
USBHALHost::USBHALHost() {
instHost = this;
}
void USBHALHost::init() {
}
uint32_t USBHALHost::controlHeadED() {
return LPC_USB->HcControlHeadED;
}
uint32_t USBHALHost::bulkHeadED() {
return LPC_USB->HcBulkHeadED;
}
uint32_t USBHALHost::interruptHeadED() {
return usb_hcca->IntTable[0];
}
void USBHALHost::updateBulkHeadED(uint32_t addr) {
LPC_USB->HcBulkHeadED = addr;
}
void USBHALHost::updateControlHeadED(uint32_t addr) {
LPC_USB->HcControlHeadED = addr;
}
void USBHALHost::updateInterruptHeadED(uint32_t addr) {
usb_hcca->IntTable[0] = addr;
}
void USBHALHost::enableList(ENDPOINT_TYPE type) {
switch(type) {
case CONTROL_ENDPOINT:
LPC_USB->HcCommandStatus = OR_CMD_STATUS_CLF;
LPC_USB->HcControl |= OR_CONTROL_CLE;
break;
case ISOCHRONOUS_ENDPOINT:
break;
case BULK_ENDPOINT:
LPC_USB->HcCommandStatus = OR_CMD_STATUS_BLF;
LPC_USB->HcControl |= OR_CONTROL_BLE;
break;
case INTERRUPT_ENDPOINT:
LPC_USB->HcControl |= OR_CONTROL_PLE;
break;
}
}
bool USBHALHost::disableList(ENDPOINT_TYPE type) {
switch(type) {
case CONTROL_ENDPOINT:
if(LPC_USB->HcControl & OR_CONTROL_CLE) {
LPC_USB->HcControl &= ~OR_CONTROL_CLE;
return true;
}
return false;
case ISOCHRONOUS_ENDPOINT:
return false;
case BULK_ENDPOINT:
if(LPC_USB->HcControl & OR_CONTROL_BLE){
LPC_USB->HcControl &= ~OR_CONTROL_BLE;
return true;
}
return false;
case INTERRUPT_ENDPOINT:
if(LPC_USB->HcControl & OR_CONTROL_PLE) {
LPC_USB->HcControl &= ~OR_CONTROL_PLE;
return true;
}
return false;
}
return false;
}
void USBHALHost::memInit() {
usb_hcca = (volatile HCCA *)usb_buf;
usb_edBuf = usb_buf + HCCA_SIZE;
usb_tdBuf = usb_buf + HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE);
}
volatile uint8_t * USBHALHost::getED() {
for (int i = 0; i < MAX_ENDPOINT; i++) {
if ( !edBufAlloc[i] ) {
edBufAlloc[i] = true;
return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE);
}
}
perror("Could not allocate ED\r\n");
return NULL; //Could not alloc ED
}
volatile uint8_t * USBHALHost::getTD() {
int i;
for (i = 0; i < MAX_TD; i++) {
if ( !tdBufAlloc[i] ) {
tdBufAlloc[i] = true;
return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE);
}
}
perror("Could not allocate TD\r\n");
return NULL; //Could not alloc TD
}
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) {
int i;
i = (td - usb_tdBuf) / TD_SIZE;
tdBufAlloc[i] = false;
}
void USBHALHost::resetRootHub() {
// Initiate port reset
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS;
while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS);
// ...and clear port reset signal
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
}
void USBHALHost::_usbisr(void) {
if (instHost) {
instHost->UsbIrqhandler();
}
}
void USBHALHost::UsbIrqhandler() {
if( LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable ) //Is there something to actually process?
{
uint32_t int_status = LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable;
// Root hub status change interrupt
if (int_status & OR_INTR_STATUS_RHSC) {
if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) {
if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) {
// When DRWE is on, Connect Status Change
// means a remote wakeup event.
} else {
//Root device connected
if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
// wait 150ms to avoid bounce
wait_ms(150);
//Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed
deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA);
}
//Root device disconnected
else {
if (!(int_status & OR_INTR_STATUS_WDH)) {
usb_hcca->DoneHead = 0;
}
// wait 200ms to avoid bounce
wait_ms(200);
deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE);
if (int_status & OR_INTR_STATUS_WDH) {
usb_hcca->DoneHead = 0;
LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH;
}
}
}
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
}
if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC) {
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
}
LPC_USB->HcInterruptStatus = OR_INTR_STATUS_RHSC;
}
// Writeback Done Head interrupt
if (int_status & OR_INTR_STATUS_WDH) {
transferCompleted(usb_hcca->DoneHead & 0xFFFFFFFE);
LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH;
}
}
}
#endif

View File

@ -47,7 +47,7 @@ USBHost * USBHost::instHost = NULL;
* - call the callback attached to the endpoint where the td is attached
*/
void USBHost::usb_process() {
bool controlListState;
bool bulkListState;
bool interruptListState;
@ -60,29 +60,29 @@ void USBHost::usb_process() {
#if DEBUG_TRANSFER
uint8_t * buf_transfer;
#endif
#if MAX_HUB_NB
uint8_t k;
#endif
while(1) {
osEvent evt = mail_usb_event.get();
if (evt.status == osEventMail) {
message_t * usb_msg = (message_t*)evt.value.p;
switch (usb_msg->event_id) {
// a new device has been connected
case DEVICE_CONNECTED_EVENT:
too_many_hub = false;
buf[4] = 0;
do
{
Lock lock(this);
for (i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if (!deviceInUse[i]) {
USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]);
@ -92,68 +92,68 @@ void USBHost::usb_process() {
break;
}
}
if (i == MAX_DEVICE_CONNECTED) {
USB_ERR("Too many device connected!!\r\n");
continue;
}
if (!controlEndpointAllocated) {
control = newEndpoint(CONTROL_ENDPOINT, OUT, 0x08, 0x00);
addEndpoint(NULL, 0, (USBEndpoint*)control);
controlEndpointAllocated = true;
}
#if MAX_HUB_NB
if (usb_msg->hub_parent)
devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent));
#endif
for (j = 0; j < timeout_set_addr; j++) {
resetDevice(&devices[i]);
// set size of control endpoint
devices[i].setSizeControlEndpoint(8);
devices[i].activeAddress(false);
// 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);
if (res != USB_TYPE_OK) {
USB_ERR("usb_thread could not read dev descr");
continue;
}
// set size of control endpoint
devices[i].setSizeControlEndpoint(buf[7]);
// second step: set an address to the device
res = setAddress(&devices[i], devices[i].getAddress());
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());
// try to read again the device descriptor to check if the device
// answers to its new address
res = getDeviceDescriptor(&devices[i], buf, 8);
if (res == USB_TYPE_OK) {
break;
}
Thread::wait(100);
}
USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port);
#if MAX_HUB_NB
if (buf[4] == HUB_CLASS) {
for (k = 0; k < MAX_HUB_NB; k++) {
@ -169,49 +169,49 @@ void USBHost::usb_process() {
break;
}
}
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);
break;
// a device has been disconnected
case DEVICE_DISCONNECTED_EVENT:
do
{
Lock lock(this);
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]);
}
if (controlListState) enableList(CONTROL_ENDPOINT);
if (bulkListState) enableList(BULK_ENDPOINT);
if (interruptListState) enableList(INTERRUPT_ENDPOINT);
} while(0);
break;
// a td has been processed
// call callback on the ed associated to the td
// we are not in ISR -> users can use printf in their callback method
@ -241,7 +241,7 @@ void USBHost::usb_process() {
}
break;
}
mail_usb_event.free(usb_msg);
}
}
@ -272,7 +272,7 @@ USBHost::USBHost() : usbThread(USBHost::usb_process_static, (void *)this, osPrio
for (uint8_t j = 0; j < MAX_INTF; j++)
deviceAttachedDriver[i][j] = false;
}
#if MAX_HUB_NB
for (uint8_t i = 0; i < MAX_HUB_NB; i++) {
hubs[i].setHost(this);
@ -313,7 +313,7 @@ void USBHost::transferCompleted(volatile uint32_t addr)
tdList = (volatile HCTD*)td->nextTD; //Dequeue element now as it could be modified below
if (td->ep != NULL) {
USBEndpoint * ep = (USBEndpoint *)(td->ep);
if (((HCTD *)td)->control >> 28) {
state = ((HCTD *)td)->control >> 28;
} else {
@ -321,9 +321,9 @@ void USBHost::transferCompleted(volatile uint32_t addr)
ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
state = 16 /*USB_TYPE_IDLE*/;
}
ep->unqueueTransfer(td);
if (ep->getType() != CONTROL_ENDPOINT) {
// callback on the processed td will be called from the usb_thread (not in ISR)
message_t * usb_msg = mail_usb_event.alloc();
@ -360,7 +360,7 @@ USBHost * USBHost::getHostInst()
if (deviceInited[idx])
return;
}
message_t * usb_msg = mail_usb_event.alloc();
usb_msg->event_id = DEVICE_CONNECTED_EVENT;
usb_msg->hub = hub;
@ -384,7 +384,7 @@ USBHost * USBHost::getHostInst()
} else {
return;
}
message_t * usb_msg = mail_usb_event.alloc();
usb_msg->event_id = DEVICE_DISCONNECTED_EVENT;
usb_msg->hub = hub;
@ -397,7 +397,7 @@ void USBHost::freeDevice(USBDeviceConnected * dev)
{
USBEndpoint * ep = NULL;
HCED * ed = NULL;
#if MAX_HUB_NB
if (dev->getClass() == HUB_CLASS) {
if (dev->hub == NULL) {
@ -412,13 +412,13 @@ void USBHost::freeDevice(USBDeviceConnected * dev)
}
}
}
// notify hub parent that this device has been disconnected
if (dev->getHubParent())
dev->getHubParent()->deviceDisconnected(dev);
#endif
int idx = findDevice(dev);
if (idx != -1) {
deviceInUse[idx] = false;
@ -481,7 +481,7 @@ void USBHost::unqueueEndpoint(USBEndpoint * ep)
updateInterruptHeadED(0);
headInterruptEndpoint = current->nextEndpoint();
}
// modify tail
switch (current->getType()) {
case BULK_ENDPOINT:
@ -553,7 +553,7 @@ USB_TYPE USBHost::resetDevice(USBDeviceConnected * dev)
deviceReset[index] = true;
return USB_TYPE_OK;
}
return USB_TYPE_ERROR;
}
@ -577,7 +577,7 @@ bool USBHost::addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint
if ((dev != NULL) && dev->getSpeed()) {
ep->setSpeed(dev->getSpeed());
}
ep->setIntfNb(intf_nb);
// queue the new USBEndpoint on the ED list
@ -626,7 +626,7 @@ bool USBHost::addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint
default:
return false;
}
ep->dev = dev;
dev->addEndpoint(intf_nb, ep);
@ -733,7 +733,7 @@ USB_TYPE USBHost::addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len)
ed->queueTransfer();
printList(type);
enableList(type);
td_mutex.unlock();
return USB_TYPE_PROCESSING;
@ -750,7 +750,7 @@ USB_TYPE USBHost::getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, u
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;
}
@ -772,10 +772,10 @@ 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)
*len_conf_descr = total_conf_descr_length;
USB_DBG("TOTAL_LENGTH: %d \t NUM_INTERF: %d", total_conf_descr_length, buf[4]);
return controlRead( dev,
@ -792,7 +792,7 @@ USB_TYPE USBHost::setAddress(USBDeviceConnected * dev, uint8_t address) {
SET_ADDRESS,
address,
0, NULL, 0);
}
USB_TYPE USBHost::setConfiguration(USBDeviceConnected * dev, uint8_t conf)
@ -821,18 +821,18 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
{
uint16_t total_conf_descr_length = 0;
USB_TYPE res;
do
{
Lock lock(this);
// 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;
}
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);
@ -840,9 +840,9 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
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);
// third step: get the whole device descriptor to see vid, pid
res = getDeviceDescriptor(dev, data, DEVICE_DESCRIPTOR_LENGTH);
@ -850,7 +850,7 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
USB_DBG("GET DEV DESCR FAILED");
return res;
}
dev->setClass(data[4]);
dev->setSubClass(data[5]);
dev->setProtocol(data[6]);
@ -877,7 +877,7 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
// 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);
@ -887,12 +887,12 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
return res;
}
}
dev->setEnumerated();
// Now the device is enumerated!
USB_DBG("dev %p is enumerated\r\n", dev);
} while(0);
// Some devices may require this delay
@ -991,17 +991,17 @@ USB_TYPE USBHost::interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint
}
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");
USB_DBG_TRANSFER("----- %s %s [dev: %p - %s - hub: %d - port: %d - addr: %d - ep: %02X]------", type_str, (write) ? "WRITE" : "READ", dev, dev->getName(ep->getIntfNb()), dev->getHub(), dev->getPort(), dev->getAddress(), ep->getAddress());
#endif
Lock lock(this);
USB_TYPE res;
ENDPOINT_DIRECTION dir = (write) ? OUT : IN;
if (dev == NULL) {
USB_ERR("dev NULL");
return USB_TYPE_ERROR;
@ -1026,7 +1026,7 @@ USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, ui
USB_ERR("[ep: %p - dev: %p] USBEndpoint addr and device addr don't match", ep, ep->dev);
return USB_TYPE_ERROR;
}
#if DEBUG_TRANSFER
if (write) {
USB_DBG_TRANSFER("%s WRITE buffer", type_str);
@ -1038,19 +1038,19 @@ USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, ui
addTransfer(ep, buf, len);
if (blocking) {
ep->ep_queue.get();
res = ep->getState();
USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep);
if (res != USB_TYPE_IDLE) {
return res;
}
return USB_TYPE_OK;
}
return USB_TYPE_PROCESSING;
}

View File

@ -35,7 +35,7 @@ public:
* Static method to create or retrieve the single USBHost instance
*/
static USBHost * getHostInst();
/**
* Control read: setup stage, data stage and status stage
*
@ -186,19 +186,19 @@ public:
dev->onDisconnect(intf, fn);
}
}
/**
* Instantiate to protect USB thread from accessing shared objects (USBConnectedDevices and Interfaces)
*/
class Lock
{
public:
Lock(USBHost* pHost);
~Lock();
Lock(USBHost* pHost);
~Lock();
private:
USBHost* m_pHost;
};
friend class USBHostHub;
protected:
@ -257,7 +257,7 @@ private:
bool deviceAttachedDriver[MAX_DEVICE_CONNECTED][MAX_INTF];
bool deviceReset[MAX_DEVICE_CONNECTED];
bool deviceInited[MAX_DEVICE_CONNECTED];
#if MAX_HUB_NB
USBHostHub hubs[MAX_HUB_NB];
bool hub_in_use[MAX_HUB_NB];
@ -265,7 +265,7 @@ private:
// to store a setup packet
uint8_t setupPacket[8];
typedef struct {
uint8_t event_id;
void * td_addr;
@ -275,17 +275,17 @@ private:
uint8_t td_state;
void * hub_parent;
} message_t;
Thread usbThread;
void usb_process();
static void usb_process_static(void const * arg);
Mail<message_t, 10> mail_usb_event;
Mutex usb_mutex;
Mutex td_mutex;
// buffer for conf descriptor
uint8_t data[415];
/**
* Add a transfer on the TD linked list associated to an ED
*
@ -296,7 +296,7 @@ private:
* @return status of the transfer
*/
USB_TYPE addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len) ;
/**
* Link the USBEndpoint to the linked list and attach an USBEndpoint this USBEndpoint to a device
*
@ -318,7 +318,7 @@ private:
* @returns pointer on the USBEndpoint created
*/
USBEndpoint * newEndpoint(ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t addr) ;
/**
* Request the device descriptor
*
@ -338,7 +338,7 @@ private:
* @param len_conf_descr pointer to store the length of the packet transferred
*/
USB_TYPE getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_conf_descr = NULL);
/**
* Set the address of a specific device
*
@ -354,7 +354,7 @@ private:
* @param conf configuration number to activate (usually 1)
*/
USB_TYPE setConfiguration(USBDeviceConnected * dev, uint8_t conf);
/**
* Free a specific device
*
@ -378,7 +378,7 @@ private:
bool blocking,
ENDPOINT_TYPE type,
bool write) ;
void fillControlBuf(uint8_t requestType, uint8_t request, uint16_t value, uint16_t index, int len) ;
void parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator) ;
int findDevice(USBDeviceConnected * dev) ;

View File

@ -56,7 +56,7 @@
/*
* Enable USB3Gmodule
*/
#define USBHOST_3GMODULE 1
#define USBHOST_3GMODULE 1
/*
* Maximum number of interfaces of a usb device

View File

@ -67,28 +67,28 @@ enum ENDPOINT_TYPE {
#define HUB_CLASS 0x09
#define SERIAL_CLASS 0x0A
// ------------------ HcControl Register ---------------------
// ------------------ HcControl Register ---------------------
#define OR_CONTROL_PLE 0x00000004
#define OR_CONTROL_CLE 0x00000010
#define OR_CONTROL_BLE 0x00000020
#define OR_CONTROL_HCFS 0x000000C0
#define OR_CONTROL_HC_OPER 0x00000080
// ----------------- HcCommandStatus Register -----------------
// ----------------- HcCommandStatus Register -----------------
#define OR_CMD_STATUS_HCR 0x00000001
#define OR_CMD_STATUS_CLF 0x00000002
#define OR_CMD_STATUS_BLF 0x00000004
// --------------- HcInterruptStatus Register -----------------
// --------------- HcInterruptStatus Register -----------------
#define OR_INTR_STATUS_WDH 0x00000002
#define OR_INTR_STATUS_RHSC 0x00000040
#define OR_INTR_STATUS_UE 0x00000010
// --------------- HcInterruptEnable Register -----------------
// --------------- HcInterruptEnable Register -----------------
#define OR_INTR_ENABLE_WDH 0x00000002
#define OR_INTR_ENABLE_RHSC 0x00000040
#define OR_INTR_ENABLE_MIE 0x80000000
// ---------------- HcRhDescriptorA Register ------------------
// ---------------- HcRhDescriptorA Register ------------------
#define OR_RH_STATUS_LPSC 0x00010000
#define OR_RH_STATUS_DRWE 0x00008000
// -------------- HcRhPortStatus[1:NDP] Register --------------
// -------------- HcRhPortStatus[1:NDP] Register --------------
#define OR_RH_PORT_CCS 0x00000001
#define OR_RH_PORT_PRS 0x00000010
#define OR_RH_PORT_CSC 0x00010000
@ -100,14 +100,14 @@ enum ENDPOINT_TYPE {
#define ED_SKIP (uint32_t) (0x00001000) // Skip this ep in queue
#define TD_ROUNDING (uint32_t) (0x00040000) // Buffer Rounding
#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
#define TD_DELAY_INT(x) (uint32_t)((x) << 21) // Delay Interrupt
#define TD_TOGGLE_0 (uint32_t)(0x02000000) // Toggle 0
#define TD_TOGGLE_1 (uint32_t)(0x03000000) // Toggle 1
#define TD_CC (uint32_t)(0xF0000000) // Completion Code
#define TD_ROUNDING (uint32_t) (0x00040000) // Buffer Rounding
#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
#define TD_DELAY_INT(x) (uint32_t)((x) << 21) // Delay Interrupt
#define TD_TOGGLE_0 (uint32_t)(0x02000000) // Toggle 0
#define TD_TOGGLE_1 (uint32_t)(0x03000000) // Toggle 1
#define TD_CC (uint32_t)(0xF0000000) // Completion Code
#define DEVICE_DESCRIPTOR (1)
#define CONFIGURATION_DESCRIPTOR (2)
@ -115,7 +115,7 @@ enum ENDPOINT_TYPE {
#define ENDPOINT_DESCRIPTOR (5)
#define HID_DESCRIPTOR (33)
// ----------- Control RequestType Fields -----------
// ----------- Control RequestType Fields -----------
#define USB_DEVICE_TO_HOST 0x80
#define USB_HOST_TO_DEVICE 0x00
#define USB_REQUEST_TYPE_CLASS 0x20
@ -124,14 +124,14 @@ enum ENDPOINT_TYPE {
#define USB_RECIPIENT_INTERFACE 0x01
#define USB_RECIPIENT_ENDPOINT 0x02
// -------------- USB Standard Requests --------------
// -------------- USB Standard Requests --------------
#define SET_ADDRESS 0x05
#define GET_DESCRIPTOR 0x06
#define SET_CONFIGURATION 0x09
#define SET_INTERFACE 0x0b
#define CLEAR_FEATURE 0x01
// -------------- USB Descriptor Length --------------
// -------------- USB Descriptor Length --------------
#define DEVICE_DESCRIPTOR_LENGTH 0x12
#define CONFIGURATION_DESCRIPTOR_LENGTH 0x09
@ -145,7 +145,7 @@ typedef struct HCTD {
uint32_t dummy[3]; // padding
} PACKED HCTD;
// ----------- HostController EndPoint Descriptor -------------
// ----------- HostController EndPoint Descriptor -------------
typedef struct hcEd {
__IO uint32_t control; // Endpoint descriptor control
__IO HCTD * tailTD; // Physical address of tail in Transfer descriptor list
@ -154,73 +154,73 @@ typedef struct hcEd {
} PACKED HCED;
// ----------- Host Controller Communication Area ------------
// ----------- Host Controller Communication Area ------------
typedef struct hcca {
__IO uint32_t IntTable[32]; // Interrupt Table
__IO uint32_t FrameNumber; // Frame Number
__IO uint32_t DoneHead; // Done Head
volatile uint8_t Reserved[116]; // Reserved for future use
volatile uint8_t Unknown[4]; // Unused
volatile uint8_t Reserved[116]; // Reserved for future use
volatile uint8_t Unknown[4]; // Unused
} PACKED HCCA;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} PACKED DeviceDescriptor;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} PACKED ConfigurationDescriptor;
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} PACKED ConfigurationDescriptor;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} InterfaceDescriptor;
uint8_t iInterface;
} InterfaceDescriptor;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} EndpointDescriptor;
typedef struct {
uint8_t bDescLength;
uint8_t bDescriptorType;
uint8_t bNbrPorts;
uint8_t bDescLength;
uint8_t bDescriptorType;
uint8_t bNbrPorts;
uint16_t wHubCharacteristics;
uint8_t bPwrOn2PwrGood;
uint8_t bHubContrCurrent;
uint8_t DeviceRemovable;
uint8_t PortPweCtrlMak;
} HubDescriptor;
uint8_t bPwrOn2PwrGood;
uint8_t bHubContrCurrent;
uint8_t DeviceRemovable;
uint8_t PortPweCtrlMak;
} HubDescriptor;
#endif

View File

@ -45,12 +45,12 @@ bool WANDongle::tryConnect()
USB_DBG("Trying to connect device");
if (dev_connected) {
USB_DBG("Device is already connected!");
USB_DBG("Device is already connected!");
return true;
}
m_pInitializer = NULL;
//Protect from concurrent access from USB thread
USBHost::Lock lock(host);
@ -59,16 +59,16 @@ bool WANDongle::tryConnect()
if ((dev = host->getDevice(i)) != NULL)
{
m_pInitializer = NULL; //Will be set in setVidPid callback
USB_DBG("Enumerate");
int ret = host->enumerate(dev, this);
if(ret)
{
return false;
}
USB_DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid());
if(m_pInitializer) //If an initializer has been found
{
USB_DBG("m_pInitializer=%p", m_pInitializer);
@ -90,18 +90,18 @@ bool WANDongle::tryConnect()
USB_DBG("Ep %p", m_pInitializer->getEp(dev, j, true));
m_serial[j].connect( dev, m_pInitializer->getEp(dev, j, false), m_pInitializer->getEp(dev, j, true) );
}
USB_DBG("Device connected");
dev_connected = true;
return true;
}
else if ((dev->getVid() == m_pInitializer->getMSDVid()) && (dev->getPid() == m_pInitializer->getMSDPid()))
{
USB_DBG("Vodafone K3370 dongle detected in MSD mode");
//Try to switch
//Try to switch
if( m_pInitializer->switchMode(dev) )
{
USB_DBG("Switched OK");

View File

@ -58,47 +58,47 @@ public:
* @return true if a serial device is connected
*/
bool connected();
/*
* Try to connect device
*
* * @return true if connection was successful
*/
bool tryConnect();
/*
* Disconnect device
*
* * @return true if disconnection was successful
*/
bool disconnect();
int getDongleType();
IUSBHostSerial& getSerial(int index);
int getSerialCount();
bool addInitializer(WANDongleInitializer* pInitializer);
//From IUSBEnumerator
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
protected:
USBHost * host;
USBDeviceConnected * dev;
bool dev_connected;
WANDongleInitializer* m_pInitializer;
void init();
WANDongleSerialPort m_serial[WANDONGLE_MAX_SERIAL_PORTS];
int m_serialCount;
int m_totalInitializers;
WANDongleInitializer* m_Initializers[WANDONGLE_MAX_INITIALIZERS];
};

View File

@ -40,29 +40,29 @@ protected:
WANDongleInitializer(USBHost* pHost) { m_pHost = pHost; }
USBHost* m_pHost;
uint8_t m_serialIntfMap[WANDONGLE_MAX_SERIAL_PORTS];
public:
virtual ~WANDongleInitializer() {}
virtual uint16_t getMSDVid() = 0;
virtual uint16_t getMSDPid() = 0;
virtual uint16_t getSerialVid() = 0;
virtual uint16_t getSerialPid() = 0;
virtual bool switchMode(USBDeviceConnected* pDev) = 0;
virtual USBEndpoint* getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx) {
return pDev->getEndpoint(m_serialIntfMap[serialPortNumber], BULK_ENDPOINT, tx ? OUT : IN, 0);
}
virtual int getSerialPortCount() = 0;
virtual void setVidPid(uint16_t vid, uint16_t pid) = 0;
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) = 0; //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) = 0; //Must return true if the endpoint will be used
virtual int getType() = 0;
virtual uint8_t getSerialIntf(int index) { return m_serialIntfMap[index]; }

View File

@ -58,7 +58,7 @@ void WANDongleSerialPort::reset()
buf_in_read_pos = 0;
lock_rx = false;
cb_rx_pending = false;
tx_mtx.unlock();
rx_mtx.unlock();
}
@ -73,7 +73,7 @@ int WANDongleSerialPort::readPacket()
rx_mtx.unlock();
return -1;
}
if( bulk_in == NULL )
{
USB_WARN("Port is disconnected");
@ -105,7 +105,7 @@ int WANDongleSerialPort::writePacket()
tx_mtx.unlock();
return -1;
}
if( bulk_out == NULL )
{
USB_WARN("Port is disconnected");

View File

@ -42,11 +42,11 @@ public:
*
*/
WANDongleSerialPort();
void init( USBHost* pHost );
void connect( USBDeviceConnected* pDev, USBEndpoint* pInEp, USBEndpoint* pOutEp );
void disconnect( );
/*
@ -89,13 +89,13 @@ public:
* @param pListener instance of the listener deriving from the IUSBHostSerialListener
*/
virtual void attach(IUSBHostSerialListener* pListener);
/**
* Enable or disable readable/writeable callbacks
*/
virtual void setupIrq(bool en, IrqType irq = RxIrq);
protected:
USBEndpoint * bulk_in;
USBEndpoint * bulk_out;
@ -117,11 +117,11 @@ protected:
volatile bool cb_rx_en;
volatile bool cb_rx_pending;
Mutex rx_mtx;
IUSBHostSerialListener* listener;
void reset();
void rxHandler();
void txHandler();

View File

@ -18,7 +18,7 @@
#if USBHOST_KEYBOARD
static uint8_t keymap[4][0x39] = {
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*/,
@ -100,30 +100,30 @@ bool USBHostKeyboard::connected() {
bool USBHostKeyboard::connect() {
if (dev_connected) {
return true;
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) {
if (host->enumerate(dev, this))
break;
if (keyboard_device_found) {
int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN);
if (!int_in)
break;
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;
return true;
}

View File

@ -23,12 +23,12 @@
#include "USBHost.h"
/**
/**
* A class to communicate a USB keyboard
*/
class USBHostKeyboard : public IUSBEnumerator {
public:
/**
* Constructor
*/
@ -83,7 +83,7 @@ private:
uint8_t report[9];
int keyboard_intf;
bool keyboard_device_found;
bool dev_connected;
void rxHandler();
@ -92,7 +92,7 @@ private:
void (*onKeyCode)(uint8_t key, uint8_t modifier);
int report_id;
void init();
};

View File

@ -35,7 +35,7 @@ void USBHostMouse::init() {
dev_connected = false;
mouse_device_found = false;
mouse_intf = -1;
buttons = 0;
x = 0;
y = 0;
@ -51,26 +51,26 @@ bool USBHostMouse::connect() {
if (dev_connected) {
return true;
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) {
if(host->enumerate(dev, this))
break;
if (mouse_device_found) {
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);
int_in->attach(this, &USBHostMouse::rxHandler);
host->interruptRead(dev, int_in, report, int_in->getSize(), false);
dev_connected = true;
return true;
}
@ -82,33 +82,33 @@ bool USBHostMouse::connect() {
void USBHostMouse::rxHandler() {
int len_listen = int_in->getSize();
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 (dev)
host->interruptRead(dev, int_in, report, len_listen, false);
}

View File

@ -23,7 +23,7 @@
#include "USBHost.h"
/**
/**
* A class to communicate a USB mouse
*/
class USBHostMouse : public IUSBEnumerator {
@ -58,7 +58,7 @@ public:
onUpdate = ptr;
}
}
/**
* Attach a callback called when the button state changes
*
@ -69,7 +69,7 @@ public:
onButtonUpdate = ptr;
}
}
/**
* Attach a callback called when the X axis value changes
*
@ -80,7 +80,7 @@ public:
onXUpdate = ptr;
}
}
/**
* Attach a callback called when the Y axis value changes
*
@ -91,7 +91,7 @@ public:
onYUpdate = ptr;
}
}
/**
* Attach a callback called when the Z axis value changes (scrolling)
*
@ -114,7 +114,7 @@ private:
USBDeviceConnected * dev;
USBEndpoint * int_in;
uint8_t report[4];
bool dev_connected;
bool mouse_device_found;
int mouse_intf;

View File

@ -64,7 +64,7 @@ void USBHostHub::init() {
hub_device_found = false;
nb_port = 0;
hub_characteristics = 0;
for (int i = 0; i < MAX_HUB_PORT; i++) {
device_children[i] = NULL;
}
@ -80,52 +80,52 @@ bool USBHostHub::connected()
}
bool USBHostHub::connect(USBDeviceConnected * dev)
{
{
if (dev_connected) {
return true;
}
if(host->enumerate(dev, this)) {
init();
return false;
}
if (hub_device_found) {
this->dev = dev;
int_in = dev->getEndpoint(hub_intf, INTERRUPT_ENDPOINT, IN);
if (!int_in) {
init();
return false;
}
USB_INFO("New HUB: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, hub_intf);
dev->setName("Hub", hub_intf);
host->registerDriver(dev, hub_intf, this, &USBHostHub::disconnect);
int_in->attach(this, &USBHostHub::rxHandler);
// get HUB descriptor
host->controlRead( dev,
host->controlRead( dev,
USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
GET_DESCRIPTOR,
0x29 << 8, 0, buf, sizeof(HubDescriptor));
nb_port = buf[2];
hub_characteristics = buf[3];
USB_DBG("Hub has %d port", nb_port);
for (uint8_t j = 1; j <= nb_port; j++) {
setPortFeature(PORT_POWER_FEATURE, j);
}
wait_ms(buf[5]*2);
host->interruptRead(dev, int_in, buf, 1, false);
dev_connected = true;
return true;
}
return false;
}
@ -184,7 +184,7 @@ void USBHostHub::rxHandler() {
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);
// if connection status has changed
if (status & C_PORT_CONNECTION) {
if (status & PORT_CONNECTION) {
@ -194,18 +194,18 @@ void USBHostHub::rxHandler() {
USB_DBG("[hub handler hub: %d - port: %d] device disconnected", dev->getHub(), port);
host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
}
clearPortFeature(C_PORT_CONNECTION_FEATURE, port);
}
if (status & C_PORT_RESET) {
clearPortFeature(C_PORT_RESET_FEATURE, port);
}
if (status & C_PORT_ENABLE) {
clearPortFeature(C_PORT_ENABLE_FEATURE, port);
}
if ((status & PORT_OVER_CURRENT)) {
USB_ERR("OVER CURRENT DETECTED\r\n");
clearPortFeature(PORT_OVER_CURRENT, port);

View File

@ -28,7 +28,7 @@ class USBHost;
class USBDeviceConnected;
class USBEndpoint;
/**
/**
* A class to use a USB Hub
*/
class USBHostHub : public IUSBEnumerator {
@ -52,7 +52,7 @@ public:
* @return true if connection was successful
*/
bool connect(USBDeviceConnected * dev);
/**
* Automatically called by USBHost when a device
* has been enumerated by usb_thread
@ -60,7 +60,7 @@ public:
* @param dev device connected
*/
void deviceConnected(USBDeviceConnected * dev);
/**
* Automatically called by USBHost when a device
* has been disconnected from this hub
@ -68,21 +68,21 @@ public:
* @param dev device disconnected
*/
void deviceDisconnected(USBDeviceConnected * dev);
/**
* Rest a specific port
*
* @param port port number
*/
void portReset(uint8_t port);
/*
* Called by USBHost to set the instance of USBHost
*
* @param host host instance
*/
void setHost(USBHost * host);
/**
* Called by USBhost when a hub has been disconnected
*/
@ -114,7 +114,7 @@ private:
uint32_t getPortStatus(uint8_t port);
USBDeviceConnected * device_children[MAX_HUB_PORT];
void init();
void disconnect();

View File

@ -65,19 +65,19 @@ bool USBHostMSD::connect()
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) {
USB_DBG("Trying to connect MSD device\r\n");
if(host->enumerate(dev, this))
break;
if (msd_device_found) {
bulk_in = dev->getEndpoint(msd_intf, BULK_ENDPOINT, IN);
bulk_out = dev->getEndpoint(msd_intf, BULK_ENDPOINT, OUT);
if (!bulk_in || !bulk_out)
continue;
USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, msd_intf);
dev->setName("MSD", msd_intf);
host->registerDriver(dev, msd_intf, this, &USBHostMSD::init);
@ -219,7 +219,7 @@ int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t
if (data) {
USB_DBG("data stage");
if (flags == HOST_TO_DEVICE) {
res = host->bulkWrite(dev, bulk_out, data, transfer_len);
if (checkResult(res, bulk_out))
return -1;
@ -242,7 +242,7 @@ int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t
if (csw.Signature != CSW_SIGNATURE) {
return -1;
}
USB_DBG("recv csw: status: %d", csw.Status);
// ModeSense?
@ -250,27 +250,27 @@ int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t
USB_DBG("request mode sense");
return SCSIRequestSense();
}
// perform reset recovery
if ((csw.Status == 2) && (cmd[0] != 0x03)) {
// send Bulk-Only Mass Storage Reset request
res = host->controlWrite( dev,
USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
BO_MASS_STORAGE_RESET,
0, msd_intf, NULL, 0);
// unstall both endpoints
res = host->controlWrite( dev,
USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
CLEAR_FEATURE,
0, bulk_in->getAddress(), NULL, 0);
res = host->controlWrite( dev,
USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
CLEAR_FEATURE,
0, bulk_out->getAddress(), NULL, 0);
}
return csw.Status;
@ -304,20 +304,20 @@ int USBHostMSD::getMaxLun() {
int USBHostMSD::disk_initialize() {
USB_DBG("FILESYSTEM: init");
U16 i, timeout = 10;
getMaxLun();
for (i = 0; i < timeout; i++) {
Thread::wait(100);
if (!testUnitReady())
break;
}
if (i == timeout) {
disk_init = false;
return -1;
}
inquiry(0, 0);
disk_init = 1;
return readCapacity();

View File

@ -24,7 +24,7 @@
#include "USBHost.h"
#include "FATFileSystem.h"
/**
/**
* A class to communicate a USB flash disk
*/
class USBHostMSD : public IUSBEnumerator, public FATFileSystem {
@ -109,7 +109,7 @@ private:
int msd_intf;
bool msd_device_found;
bool disk_init;
void init();
};

View File

@ -24,7 +24,7 @@
template<typename T, int size>
class MtxCircBuffer {
public:
MtxCircBuffer() {
write = 0;
read = 0;
@ -43,7 +43,7 @@ public:
mtx.unlock();
return r;
}
void flush() {
write = 0;
read = 0;

View File

@ -26,7 +26,7 @@
#if (USBHOST_SERIAL <= 1)
USBHostSerial::USBHostSerial()
USBHostSerial::USBHostSerial()
{
host = USBHost::getHostInst();
ports_found = 0;
@ -46,9 +46,9 @@ void USBHostSerial::disconnect(void)
bool USBHostSerial::connect() {
if (dev)
if (dev)
{
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (dev == d)
@ -56,15 +56,15 @@ bool USBHostSerial::connect() {
}
disconnect();
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (d != NULL) {
USB_DBG("Trying to connect serial device \r\n");
if(host->enumerate(d, this))
break;
USBEndpoint* bulk_in = d->getEndpoint(port_intf, BULK_ENDPOINT, IN);
USBEndpoint* bulk_out = d->getEndpoint(port_intf, BULK_ENDPOINT, OUT);
if (bulk_in && bulk_out)
@ -84,7 +84,7 @@ bool USBHostSerial::connect() {
/*virtual*/ bool USBHostSerial::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 (!ports_found &&
if (!ports_found &&
CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
port_intf = intf_nb;
ports_found = true;
@ -96,7 +96,7 @@ bool USBHostSerial::connect() {
/*virtual*/ bool USBHostSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if (ports_found && (intf_nb == port_intf)) {
if (type == BULK_ENDPOINT)
if (type == BULK_ENDPOINT)
return true;
}
return false;
@ -106,7 +106,7 @@ bool USBHostSerial::connect() {
//------------------------------------------------------------------------------
USBHostMultiSerial::USBHostMultiSerial()
USBHostMultiSerial::USBHostMultiSerial()
{
host = USBHost::getHostInst();
dev = NULL;
@ -127,7 +127,7 @@ bool USBHostMultiSerial::connected()
void USBHostMultiSerial::disconnect(void)
{
for (int port = 0; port < USBHOST_SERIAL; port ++)
for (int port = 0; port < USBHOST_SERIAL; port ++)
{
if (ports[port])
{
@ -141,9 +141,9 @@ void USBHostMultiSerial::disconnect(void)
bool USBHostMultiSerial::connect() {
if (dev)
if (dev)
{
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (dev == d)
@ -151,16 +151,16 @@ bool USBHostMultiSerial::connect() {
}
disconnect();
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (d != NULL) {
USB_DBG("Trying to connect serial device \r\n");
if(host->enumerate(d, this))
break;
for (int port = 0; port < ports_found; port ++)
for (int port = 0; port < ports_found; port ++)
{
USBEndpoint* bulk_in = d->getEndpoint(port_intf[port], BULK_ENDPOINT, IN);
USBEndpoint* bulk_out = d->getEndpoint(port_intf[port], BULK_ENDPOINT, OUT);
@ -186,7 +186,7 @@ bool USBHostMultiSerial::connect() {
/*virtual*/ bool USBHostMultiSerial::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 ((ports_found < USBHOST_SERIAL) &&
if ((ports_found < USBHOST_SERIAL) &&
CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
port_intf[ports_found++] = intf_nb;
return true;
@ -197,7 +197,7 @@ bool USBHostMultiSerial::connect() {
/*virtual*/ bool USBHostMultiSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if ((ports_found > 0) && (intf_nb == port_intf[ports_found-1])) {
if (type == BULK_ENDPOINT)
if (type == BULK_ENDPOINT)
return true;
}
return false;
@ -209,7 +209,7 @@ bool USBHostMultiSerial::connect() {
#define SET_LINE_CODING 0x20
USBHostSerialPort::USBHostSerialPort(): circ_buf()
USBHostSerialPort::USBHostSerialPort(): circ_buf()
{
init();
}
@ -230,7 +230,7 @@ void USBHostSerialPort::init(void)
circ_buf.flush();
}
void USBHostSerialPort::connect(USBHost* _host, USBDeviceConnected * _dev,
void USBHostSerialPort::connect(USBHost* _host, USBDeviceConnected * _dev,
uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out)
{
host = _host;
@ -238,7 +238,7 @@ void USBHostSerialPort::connect(USBHost* _host, USBDeviceConnected * _dev,
serial_intf = _serial_intf;
bulk_in = _bulk_in;
bulk_out = _bulk_out;
USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf);
dev->setName("Serial", serial_intf);
host->registerDriver(dev, serial_intf, this, &USBHostSerialPort::init);
@ -289,7 +289,7 @@ void USBHostSerialPort::format(int bits, Parity parity, int stop_bits) {
line_coding.data_bits = bits;
line_coding.parity = parity;
line_coding.stop_bits = (stop_bits == 1) ? 0 : 2;
// set line coding
host->controlWrite( dev,
USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
@ -311,12 +311,12 @@ int USBHostSerialPort::_getc() {
int USBHostSerialPort::writeBuf(const char* b, int s)
{
int c = 0;
if (bulk_out)
if (bulk_out)
{
while (c < s)
{
int i = (s < size_bulk_out) ? s : size_bulk_out;
if (host->bulkWrite(dev, bulk_out, (uint8_t *)(b+c), i) == USB_TYPE_OK)
if (host->bulkWrite(dev, bulk_out, (uint8_t *)(b+c), i) == USB_TYPE_OK)
c += i;
}
}
@ -326,7 +326,7 @@ int USBHostSerialPort::writeBuf(const char* b, int s)
int USBHostSerialPort::readBuf(char* b, int s)
{
int i = 0;
if (bulk_in)
if (bulk_in)
{
for (i = 0; i < s; )
b[i++] = getc();

View File

@ -25,7 +25,7 @@
#include "Stream.h"
#include "MtxCircBuffer.h"
/**
/**
* A class to communicate a USB virtual serial port
*/
class USBHostSerialPort : public Stream {
@ -39,7 +39,7 @@ public:
RxIrq,
TxIrq
};
enum Parity {
None = 0,
Odd,
@ -48,7 +48,7 @@ public:
Space
};
void connect(USBHost* _host, USBDeviceConnected * _dev,
void connect(USBHost* _host, USBDeviceConnected * _dev,
uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out);
/**
@ -56,7 +56,7 @@ public:
*
* @returns the number of bytes available
*/
uint8_t available();
uint8_t available();
/**
* Attach a member function to call when a packet is received.
@ -90,13 +90,13 @@ public:
}
}
}
/** Set the baud rate of the serial port
*
* @param baudrate The baudrate of the serial port (default = 9600).
*/
void baud(int baudrate = 9600);
/** Set the transmission format used by the Serial port
*
* @param bits The number of bits in a word (default = 8)
@ -110,7 +110,7 @@ public:
protected:
virtual int _getc();
virtual int _putc(int c);
private:
USBHost * host;
USBDeviceConnected * dev;
@ -132,7 +132,7 @@ private:
uint8_t parity;
uint8_t data_bits;
} PACKED LINE_CODING;
LINE_CODING line_coding;
void rxHandler();
@ -145,18 +145,18 @@ private:
#if (USBHOST_SERIAL <= 1)
class USBHostSerial : public IUSBEnumerator, public USBHostSerialPort
class USBHostSerial : public IUSBEnumerator, public USBHostSerialPort
{
public:
public:
USBHostSerial();
/**
* Try to connect a serial device
*
* @return true if connection was successful
*/
bool connect();
void disconnect();
/**
@ -165,7 +165,7 @@ public:
* @returns true if a serial device is connected
*/
bool connected();
protected:
USBHost* host;
USBDeviceConnected* dev;
@ -176,7 +176,7 @@ protected:
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
private:
bool dev_connected;
};
@ -184,13 +184,13 @@ private:
#else // (USBHOST_SERIAL > 1)
class USBHostMultiSerial : public IUSBEnumerator {
public:
public:
USBHostMultiSerial();
virtual ~USBHostMultiSerial();
USBHostSerialPort* getPort(int port)
{
return port < USBHOST_SERIAL ? ports[port] : NULL;
USBHostSerialPort* getPort(int port)
{
return port < USBHOST_SERIAL ? ports[port] : NULL;
}
/**
@ -199,7 +199,7 @@ public:
* @return true if connection was successful
*/
bool connect();
void disconnect();
/**
@ -208,7 +208,7 @@ public:
* @returns true if a serial device is connected
*/
bool connected();
protected:
USBHost* host;
USBDeviceConnected* dev;
@ -220,7 +220,7 @@ protected:
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
private:
bool dev_connected;
};