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) { INTERFACE * USBDeviceConnected::getInterface(uint8_t index) {
if (index >= MAX_INTF) if (index >= MAX_INTF)
return NULL; return NULL;
if (intf[index].in_use) if (intf[index].in_use)
return &intf[index]; return &intf[index];
return NULL; return NULL;
} }

View File

@ -33,7 +33,7 @@ typedef struct {
USBEndpoint * ep[MAX_ENDPOINT_PER_INTERFACE]; USBEndpoint * ep[MAX_ENDPOINT_PER_INTERFACE];
FunctionPointer detach; FunctionPointer detach;
char name[10]; char name[10];
} INTERFACE; } INTERFACE;
/** /**
* USBDeviceConnected class * USBDeviceConnected class
@ -157,7 +157,7 @@ public:
inline USBHostHub * getHubParent() { return hub_parent; }; inline USBHostHub * getHubParent() { return hub_parent; };
inline uint8_t getNbIntf() { return nb_interf; }; inline uint8_t getNbIntf() { return nb_interf; };
inline const char * getName(uint8_t intf_nb) { return intf[intf_nb].name; }; inline const char * getName(uint8_t intf_nb) { return intf[intf_nb].name; };
// in case this device is a hub // in case this device is a hub
USBHostHub * 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 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_[0], 0, sizeof(HCTD));
memset(td_list_[1], 0, sizeof(HCTD)); memset(td_list_[1], 0, sizeof(HCTD));
td_list[0]->ep = this; td_list[0]->ep = this;
td_list[1]->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_current = td_list[0];
td_next = td_list[1]; td_next = td_list[1];
intf_nb = 0; intf_nb = 0;
state = USB_TYPE_IDLE; state = USB_TYPE_IDLE;

View File

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

View File

@ -57,7 +57,7 @@ USBHALHost::USBHALHost() {
void USBHALHost::init() { void USBHALHost::init() {
NVIC_DisableIRQ(USB_IRQn); NVIC_DisableIRQ(USB_IRQn);
//Cut power //Cut power
LPC_SC->PCONP &= ~(1UL<<31); LPC_SC->PCONP &= ~(1UL<<31);
wait_ms(100); wait_ms(100);
@ -98,7 +98,7 @@ void USBHALHost::init() {
// software reset // software reset
LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR; LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
// Write Fm Interval and Largest Data Packet Counter // Write Fm Interval and Largest Data Packet Counter
LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL;
LPC_USB->HcPeriodicStart = FI * 90 / 100; LPC_USB->HcPeriodicStart = FI * 90 / 100;
@ -109,7 +109,7 @@ void USBHALHost::init() {
LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC;
LPC_USB->HcHCCA = (uint32_t)(usb_hcca); LPC_USB->HcHCCA = (uint32_t)(usb_hcca);
// Clear Interrrupt Status // Clear Interrrupt Status
LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus;
@ -249,9 +249,9 @@ void USBHALHost::freeTD(volatile uint8_t * td) {
void USBHALHost::resetRootHub() { void USBHALHost::resetRootHub() {
// Initiate port reset // Initiate port reset
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS;
while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS); while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS);
// ...and clear port reset signal // ...and clear port reset signal
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
} }
@ -266,11 +266,11 @@ void USBHALHost::_usbisr(void) {
void USBHALHost::UsbIrqhandler() { void USBHALHost::UsbIrqhandler() {
if( LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable ) //Is there something to actually process? if( LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable ) //Is there something to actually process?
{ {
uint32_t int_status = LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable; uint32_t int_status = LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable;
// Root hub status change interrupt // 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->HcRhPortStatus1 & OR_RH_PORT_CSC) {
if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) { if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) {
// When DRWE is on, Connect Status Change // When DRWE is on, Connect Status Change
@ -278,27 +278,27 @@ void USBHALHost::UsbIrqhandler() {
} else { } else {
//Root device connected //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 150ms to avoid bounce
wait_ms(150); wait_ms(150);
//Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed //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 //Root device disconnected
else { else {
if (!(int_status & OR_INTR_STATUS_WDH)) { if (!(int_status & OR_INTR_STATUS_WDH)) {
usb_hcca->DoneHead = 0; usb_hcca->DoneHead = 0;
} }
// wait 200ms to avoid bounce // wait 200ms to avoid bounce
wait_ms(200); wait_ms(200);
deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE); deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE);
if (int_status & OR_INTR_STATUS_WDH) { if (int_status & OR_INTR_STATUS_WDH) {
usb_hcca->DoneHead = 0; usb_hcca->DoneHead = 0;
LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH; 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 * init variables and memory where will be stored HCCA, ED and TD
*/ */
USBHALHost(); 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 * this function calls a virtual method if a device is already connected
*/ */
void init(); void init();
/** /**
* reset the root hub * reset the root hub
*/ */
void resetRootHub(); void resetRootHub();
/** /**
* return the value contained in the control HEAD ED register * return the value contained in the control HEAD ED register
* *
* @returns address of the control Head ED * @returns address of the control Head ED
*/ */
uint32_t controlHeadED(); uint32_t controlHeadED();
/** /**
* return the value contained in the bulk HEAD ED register * return the value contained in the bulk HEAD ED register
* *
* @returns address of the bulk head ED * @returns address of the bulk head ED
*/ */
uint32_t bulkHeadED(); uint32_t bulkHeadED();
/** /**
* return the value of the head interrupt ED contained in the HCCA * return the value of the head interrupt ED contained in the HCCA
* *
* @returns address of the head interrupt ED contained in the HCCA * @returns address of the head interrupt ED contained in the HCCA
*/ */
uint32_t interruptHeadED(); uint32_t interruptHeadED();
/** /**
* Update the head ED for control transfers * Update the head ED for control transfers
*/ */
void updateControlHeadED(uint32_t addr); void updateControlHeadED(uint32_t addr);
/** /**
* Update the head ED for bulk transfers * Update the head ED for bulk transfers
*/ */
void updateBulkHeadED(uint32_t addr); void updateBulkHeadED(uint32_t addr);
/** /**
* Update the head ED for interrupt transfers * Update the head ED for interrupt transfers
*/ */
void updateInterruptHeadED(uint32_t addr); void updateInterruptHeadED(uint32_t addr);
/** /**
* Enable List for the specified endpoint type * Enable List for the specified endpoint type
* *
* @param type enable the list of ENDPOINT_TYPE type * @param type enable the list of ENDPOINT_TYPE type
*/ */
void enableList(ENDPOINT_TYPE type); void enableList(ENDPOINT_TYPE type);
/** /**
* Disable List for the specified endpoint 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) * @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 void deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent = NULL) = 0;
/** /**
* Virtual method called when a device has been disconnected * 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 * @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 void deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr) = 0;
/** /**
* Virtual method called when a transfer has been completed * Virtual method called when a transfer has been completed
* *
* @param addr list of the TDs which have been completed * @param addr list of the TDs which have been completed
*/ */
virtual void transferCompleted(volatile uint32_t addr) = 0; virtual void transferCompleted(volatile uint32_t addr) = 0;
/** /**
* Find a memory section for a new ED * Find a memory section for a new ED
* *
* @returns the address of the new ED * @returns the address of the new ED
*/ */
volatile uint8_t * getED(); volatile uint8_t * getED();
/** /**
* Find a memory section for a new TD * Find a memory section for a new TD
* *
* @returns the address of the new TD * @returns the address of the new TD
*/ */
volatile uint8_t * getTD(); volatile uint8_t * getTD();
/** /**
* Release a previous memory section reserved for an ED * Release a previous memory section reserved for an ED
* *
* @param ed address of the ED * @param ed address of the ED
*/ */
void freeED(volatile uint8_t * ed); void freeED(volatile uint8_t * ed);
/** /**
* Release a previous memory section reserved for an TD * Release a previous memory section reserved for an TD
* *
@ -161,7 +161,7 @@ private:
uint8_t volatile * usb_tdBuf; //4 bytes aligned uint8_t volatile * usb_tdBuf; //4 bytes aligned
static USBHALHost * instHost; static USBHALHost * instHost;
bool volatile edBufAlloc[MAX_ENDPOINT]; bool volatile edBufAlloc[MAX_ENDPOINT];
bool volatile tdBufAlloc[MAX_TD]; 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 * - call the callback attached to the endpoint where the td is attached
*/ */
void USBHost::usb_process() { void USBHost::usb_process() {
bool controlListState; bool controlListState;
bool bulkListState; bool bulkListState;
bool interruptListState; bool interruptListState;
@ -60,29 +60,29 @@ void USBHost::usb_process() {
#if DEBUG_TRANSFER #if DEBUG_TRANSFER
uint8_t * buf_transfer; uint8_t * buf_transfer;
#endif #endif
#if MAX_HUB_NB #if MAX_HUB_NB
uint8_t k; uint8_t k;
#endif #endif
while(1) { while(1) {
osEvent evt = mail_usb_event.get(); osEvent evt = mail_usb_event.get();
if (evt.status == osEventMail) { if (evt.status == osEventMail) {
message_t * usb_msg = (message_t*)evt.value.p; message_t * usb_msg = (message_t*)evt.value.p;
switch (usb_msg->event_id) { switch (usb_msg->event_id) {
// a new device has been connected // a new device has been connected
case DEVICE_CONNECTED_EVENT: case DEVICE_CONNECTED_EVENT:
too_many_hub = false; too_many_hub = false;
buf[4] = 0; buf[4] = 0;
do do
{ {
Lock lock(this); Lock lock(this);
for (i = 0; i < MAX_DEVICE_CONNECTED; i++) { for (i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if (!deviceInUse[i]) { if (!deviceInUse[i]) {
USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]); USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]);
@ -92,68 +92,68 @@ void USBHost::usb_process() {
break; break;
} }
} }
if (i == MAX_DEVICE_CONNECTED) { if (i == MAX_DEVICE_CONNECTED) {
USB_ERR("Too many device connected!!\r\n"); USB_ERR("Too many device connected!!\r\n");
continue; continue;
} }
if (!controlEndpointAllocated) { if (!controlEndpointAllocated) {
control = newEndpoint(CONTROL_ENDPOINT, OUT, 0x08, 0x00); control = newEndpoint(CONTROL_ENDPOINT, OUT, 0x08, 0x00);
addEndpoint(NULL, 0, (USBEndpoint*)control); addEndpoint(NULL, 0, (USBEndpoint*)control);
controlEndpointAllocated = true; controlEndpointAllocated = true;
} }
#if MAX_HUB_NB #if MAX_HUB_NB
if (usb_msg->hub_parent) if (usb_msg->hub_parent)
devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent)); devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent));
#endif #endif
for (j = 0; j < timeout_set_addr; j++) { for (j = 0; j < timeout_set_addr; j++) {
resetDevice(&devices[i]); resetDevice(&devices[i]);
// set size of control endpoint // set size of control endpoint
devices[i].setSizeControlEndpoint(8); devices[i].setSizeControlEndpoint(8);
devices[i].activeAddress(false); devices[i].activeAddress(false);
// get first 8 bit of device descriptor // get first 8 bit of device descriptor
// and check if we deal with a hub // and check if we deal with a hub
USB_DBG("usb_thread read device descriptor on dev: %p\r\n", &devices[i]); USB_DBG("usb_thread read device descriptor on dev: %p\r\n", &devices[i]);
res = getDeviceDescriptor(&devices[i], buf, 8); res = getDeviceDescriptor(&devices[i], buf, 8);
if (res != USB_TYPE_OK) { if (res != USB_TYPE_OK) {
USB_ERR("usb_thread could not read dev descr"); USB_ERR("usb_thread could not read dev descr");
continue; continue;
} }
// set size of control endpoint // set size of control endpoint
devices[i].setSizeControlEndpoint(buf[7]); devices[i].setSizeControlEndpoint(buf[7]);
// second step: set an address to the device // second step: set an address to the device
res = setAddress(&devices[i], devices[i].getAddress()); res = setAddress(&devices[i], devices[i].getAddress());
if (res != USB_TYPE_OK) { if (res != USB_TYPE_OK) {
USB_ERR("SET ADDR FAILED"); USB_ERR("SET ADDR FAILED");
continue; continue;
} }
devices[i].activeAddress(true); devices[i].activeAddress(true);
USB_DBG("Address of %p: %d", &devices[i], devices[i].getAddress()); USB_DBG("Address of %p: %d", &devices[i], devices[i].getAddress());
// try to read again the device descriptor to check if the device // try to read again the device descriptor to check if the device
// answers to its new address // answers to its new address
res = getDeviceDescriptor(&devices[i], buf, 8); res = getDeviceDescriptor(&devices[i], buf, 8);
if (res == USB_TYPE_OK) { if (res == USB_TYPE_OK) {
break; break;
} }
Thread::wait(100); Thread::wait(100);
} }
USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port); USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port);
#if MAX_HUB_NB #if MAX_HUB_NB
if (buf[4] == HUB_CLASS) { if (buf[4] == HUB_CLASS) {
for (k = 0; k < MAX_HUB_NB; k++) { for (k = 0; k < MAX_HUB_NB; k++) {
@ -169,49 +169,49 @@ void USBHost::usb_process() {
break; break;
} }
} }
if (k == MAX_HUB_NB) { if (k == MAX_HUB_NB) {
USB_ERR("Too many hubs connected!!\r\n"); USB_ERR("Too many hubs connected!!\r\n");
too_many_hub = true; too_many_hub = true;
} }
} }
if (usb_msg->hub_parent) if (usb_msg->hub_parent)
((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]); ((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]);
#endif #endif
if ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) { if ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) {
deviceInUse[i] = true; deviceInUse[i] = true;
} }
} while(0); } while(0);
break; break;
// a device has been disconnected // a device has been disconnected
case DEVICE_DISCONNECTED_EVENT: case DEVICE_DISCONNECTED_EVENT:
do do
{ {
Lock lock(this); Lock lock(this);
controlListState = disableList(CONTROL_ENDPOINT); controlListState = disableList(CONTROL_ENDPOINT);
bulkListState = disableList(BULK_ENDPOINT); bulkListState = disableList(BULK_ENDPOINT);
interruptListState = disableList(INTERRUPT_ENDPOINT); interruptListState = disableList(INTERRUPT_ENDPOINT);
idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent)); idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent));
if (idx != -1) { if (idx != -1) {
freeDevice((USBDeviceConnected*)&devices[idx]); freeDevice((USBDeviceConnected*)&devices[idx]);
} }
if (controlListState) enableList(CONTROL_ENDPOINT); if (controlListState) enableList(CONTROL_ENDPOINT);
if (bulkListState) enableList(BULK_ENDPOINT); if (bulkListState) enableList(BULK_ENDPOINT);
if (interruptListState) enableList(INTERRUPT_ENDPOINT); if (interruptListState) enableList(INTERRUPT_ENDPOINT);
} while(0); } while(0);
break; break;
// a td has been processed // a td has been processed
// call callback on the ed associated to the td // call callback on the ed associated to the td
// we are not in ISR -> users can use printf in their callback method // we are not in ISR -> users can use printf in their callback method
@ -241,7 +241,7 @@ void USBHost::usb_process() {
} }
break; break;
} }
mail_usb_event.free(usb_msg); 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++) for (uint8_t j = 0; j < MAX_INTF; j++)
deviceAttachedDriver[i][j] = false; deviceAttachedDriver[i][j] = false;
} }
#if MAX_HUB_NB #if MAX_HUB_NB
for (uint8_t i = 0; i < MAX_HUB_NB; i++) { for (uint8_t i = 0; i < MAX_HUB_NB; i++) {
hubs[i].setHost(this); 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 tdList = (volatile HCTD*)td->nextTD; //Dequeue element now as it could be modified below
if (td->ep != NULL) { if (td->ep != NULL) {
USBEndpoint * ep = (USBEndpoint *)(td->ep); USBEndpoint * ep = (USBEndpoint *)(td->ep);
if (((HCTD *)td)->control >> 28) { if (((HCTD *)td)->control >> 28) {
state = ((HCTD *)td)->control >> 28; state = ((HCTD *)td)->control >> 28;
} else { } else {
@ -321,9 +321,9 @@ void USBHost::transferCompleted(volatile uint32_t addr)
ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart()); ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
state = 16 /*USB_TYPE_IDLE*/; state = 16 /*USB_TYPE_IDLE*/;
} }
ep->unqueueTransfer(td); ep->unqueueTransfer(td);
if (ep->getType() != CONTROL_ENDPOINT) { if (ep->getType() != CONTROL_ENDPOINT) {
// callback on the processed td will be called from the usb_thread (not in ISR) // callback on the processed td will be called from the usb_thread (not in ISR)
message_t * usb_msg = mail_usb_event.alloc(); message_t * usb_msg = mail_usb_event.alloc();
@ -360,7 +360,7 @@ USBHost * USBHost::getHostInst()
if (deviceInited[idx]) if (deviceInited[idx])
return; return;
} }
message_t * usb_msg = mail_usb_event.alloc(); message_t * usb_msg = mail_usb_event.alloc();
usb_msg->event_id = DEVICE_CONNECTED_EVENT; usb_msg->event_id = DEVICE_CONNECTED_EVENT;
usb_msg->hub = hub; usb_msg->hub = hub;
@ -384,7 +384,7 @@ USBHost * USBHost::getHostInst()
} else { } else {
return; return;
} }
message_t * usb_msg = mail_usb_event.alloc(); message_t * usb_msg = mail_usb_event.alloc();
usb_msg->event_id = DEVICE_DISCONNECTED_EVENT; usb_msg->event_id = DEVICE_DISCONNECTED_EVENT;
usb_msg->hub = hub; usb_msg->hub = hub;
@ -397,7 +397,7 @@ void USBHost::freeDevice(USBDeviceConnected * dev)
{ {
USBEndpoint * ep = NULL; USBEndpoint * ep = NULL;
HCED * ed = NULL; HCED * ed = NULL;
#if MAX_HUB_NB #if MAX_HUB_NB
if (dev->getClass() == HUB_CLASS) { if (dev->getClass() == HUB_CLASS) {
if (dev->hub == NULL) { if (dev->hub == NULL) {
@ -412,13 +412,13 @@ void USBHost::freeDevice(USBDeviceConnected * dev)
} }
} }
} }
// notify hub parent that this device has been disconnected // notify hub parent that this device has been disconnected
if (dev->getHubParent()) if (dev->getHubParent())
dev->getHubParent()->deviceDisconnected(dev); dev->getHubParent()->deviceDisconnected(dev);
#endif #endif
int idx = findDevice(dev); int idx = findDevice(dev);
if (idx != -1) { if (idx != -1) {
deviceInUse[idx] = false; deviceInUse[idx] = false;
@ -481,7 +481,7 @@ void USBHost::unqueueEndpoint(USBEndpoint * ep)
updateInterruptHeadED(0); updateInterruptHeadED(0);
headInterruptEndpoint = current->nextEndpoint(); headInterruptEndpoint = current->nextEndpoint();
} }
// modify tail // modify tail
switch (current->getType()) { switch (current->getType()) {
case BULK_ENDPOINT: case BULK_ENDPOINT:
@ -553,7 +553,7 @@ USB_TYPE USBHost::resetDevice(USBDeviceConnected * dev)
deviceReset[index] = true; deviceReset[index] = true;
return USB_TYPE_OK; return USB_TYPE_OK;
} }
return USB_TYPE_ERROR; return USB_TYPE_ERROR;
} }
@ -577,7 +577,7 @@ bool USBHost::addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint
if ((dev != NULL) && dev->getSpeed()) { if ((dev != NULL) && dev->getSpeed()) {
ep->setSpeed(dev->getSpeed()); ep->setSpeed(dev->getSpeed());
} }
ep->setIntfNb(intf_nb); ep->setIntfNb(intf_nb);
// queue the new USBEndpoint on the ED list // queue the new USBEndpoint on the ED list
@ -626,7 +626,7 @@ bool USBHost::addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint
default: default:
return false; return false;
} }
ep->dev = dev; ep->dev = dev;
dev->addEndpoint(intf_nb, ep); dev->addEndpoint(intf_nb, ep);
@ -733,7 +733,7 @@ USB_TYPE USBHost::addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len)
ed->queueTransfer(); ed->queueTransfer();
printList(type); printList(type);
enableList(type); enableList(type);
td_mutex.unlock(); td_mutex.unlock();
return USB_TYPE_PROCESSING; 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)); 0, buf, MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf));
if (len_dev_descr) if (len_dev_descr)
*len_dev_descr = MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf); *len_dev_descr = MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf);
return t; return t;
} }
@ -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 = buf[2] | (buf[3] << 8);
total_conf_descr_length = MIN(max_len_buf, total_conf_descr_length); total_conf_descr_length = MIN(max_len_buf, total_conf_descr_length);
if (len_conf_descr) if (len_conf_descr)
*len_conf_descr = total_conf_descr_length; *len_conf_descr = total_conf_descr_length;
USB_DBG("TOTAL_LENGTH: %d \t NUM_INTERF: %d", total_conf_descr_length, buf[4]); USB_DBG("TOTAL_LENGTH: %d \t NUM_INTERF: %d", total_conf_descr_length, buf[4]);
return controlRead( dev, return controlRead( dev,
@ -792,7 +792,7 @@ USB_TYPE USBHost::setAddress(USBDeviceConnected * dev, uint8_t address) {
SET_ADDRESS, SET_ADDRESS,
address, address,
0, NULL, 0); 0, NULL, 0);
} }
USB_TYPE USBHost::setConfiguration(USBDeviceConnected * dev, uint8_t conf) 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; uint16_t total_conf_descr_length = 0;
USB_TYPE res; USB_TYPE res;
do do
{ {
Lock lock(this); Lock lock(this);
// don't enumerate a device which all interfaces are registered to a specific driver // don't enumerate a device which all interfaces are registered to a specific driver
int index = findDevice(dev); int index = findDevice(dev);
if (index == -1) { if (index == -1) {
return USB_TYPE_ERROR; return USB_TYPE_ERROR;
} }
uint8_t nb_intf_attached = numberDriverAttached(dev); uint8_t nb_intf_attached = numberDriverAttached(dev);
USB_DBG("dev: %p nb_intf: %d", dev, dev->getNbIntf()); USB_DBG("dev: %p nb_intf: %d", dev, dev->getNbIntf());
USB_DBG("dev: %p nb_intf_attached: %d", dev, nb_intf_attached); 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); USB_DBG("Don't enumerate dev: %p because all intf are registered with a driver", dev);
return USB_TYPE_OK; 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 // third step: get the whole device descriptor to see vid, pid
res = getDeviceDescriptor(dev, data, DEVICE_DESCRIPTOR_LENGTH); 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"); USB_DBG("GET DEV DESCR FAILED");
return res; return res;
} }
dev->setClass(data[4]); dev->setClass(data[4]);
dev->setSubClass(data[5]); dev->setSubClass(data[5]);
dev->setProtocol(data[6]); dev->setProtocol(data[6]);
@ -877,7 +877,7 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
// only set configuration if not enumerated before // only set configuration if not enumerated before
if (!dev->isEnumerated()) { if (!dev->isEnumerated()) {
USB_DBG("Set configuration 1 on dev: %p", dev); USB_DBG("Set configuration 1 on dev: %p", dev);
// sixth step: set configuration (only 1 supported) // sixth step: set configuration (only 1 supported)
res = setConfiguration(dev, 1); res = setConfiguration(dev, 1);
@ -887,12 +887,12 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
return res; return res;
} }
} }
dev->setEnumerated(); dev->setEnumerated();
// Now the device is enumerated! // Now the device is enumerated!
USB_DBG("dev %p is enumerated\r\n", dev); USB_DBG("dev %p is enumerated\r\n", dev);
} while(0); } while(0);
// Some devices may require this delay // 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) { USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking, ENDPOINT_TYPE type, bool write) {
#if DEBUG_TRANSFER #if DEBUG_TRANSFER
const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : "ISOCHRONOUS"); const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : "ISOCHRONOUS");
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()); 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 #endif
Lock lock(this); Lock lock(this);
USB_TYPE res; USB_TYPE res;
ENDPOINT_DIRECTION dir = (write) ? OUT : IN; ENDPOINT_DIRECTION dir = (write) ? OUT : IN;
if (dev == NULL) { if (dev == NULL) {
USB_ERR("dev NULL"); USB_ERR("dev NULL");
return USB_TYPE_ERROR; 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); USB_ERR("[ep: %p - dev: %p] USBEndpoint addr and device addr don't match", ep, ep->dev);
return USB_TYPE_ERROR; return USB_TYPE_ERROR;
} }
#if DEBUG_TRANSFER #if DEBUG_TRANSFER
if (write) { if (write) {
USB_DBG_TRANSFER("%s WRITE buffer", type_str); USB_DBG_TRANSFER("%s WRITE buffer", type_str);
@ -1038,19 +1038,19 @@ USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, ui
addTransfer(ep, buf, len); addTransfer(ep, buf, len);
if (blocking) { if (blocking) {
ep->ep_queue.get(); ep->ep_queue.get();
res = ep->getState(); res = ep->getState();
USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep); USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep);
if (res != USB_TYPE_IDLE) { if (res != USB_TYPE_IDLE) {
return res; return res;
} }
return USB_TYPE_OK; return USB_TYPE_OK;
} }
return USB_TYPE_PROCESSING; return USB_TYPE_PROCESSING;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -40,29 +40,29 @@ protected:
WANDongleInitializer(USBHost* pHost) { m_pHost = pHost; } WANDongleInitializer(USBHost* pHost) { m_pHost = pHost; }
USBHost* m_pHost; USBHost* m_pHost;
uint8_t m_serialIntfMap[WANDONGLE_MAX_SERIAL_PORTS]; uint8_t m_serialIntfMap[WANDONGLE_MAX_SERIAL_PORTS];
public: public:
virtual ~WANDongleInitializer() {} virtual ~WANDongleInitializer() {}
virtual uint16_t getMSDVid() = 0; virtual uint16_t getMSDVid() = 0;
virtual uint16_t getMSDPid() = 0; virtual uint16_t getMSDPid() = 0;
virtual uint16_t getSerialVid() = 0; virtual uint16_t getSerialVid() = 0;
virtual uint16_t getSerialPid() = 0; virtual uint16_t getSerialPid() = 0;
virtual bool switchMode(USBDeviceConnected* pDev) = 0; virtual bool switchMode(USBDeviceConnected* pDev) = 0;
virtual USBEndpoint* getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx) { virtual USBEndpoint* getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx) {
return pDev->getEndpoint(m_serialIntfMap[serialPortNumber], BULK_ENDPOINT, tx ? OUT : IN, 0); return pDev->getEndpoint(m_serialIntfMap[serialPortNumber], BULK_ENDPOINT, tx ? OUT : IN, 0);
} }
virtual int getSerialPortCount() = 0; virtual int getSerialPortCount() = 0;
virtual void setVidPid(uint16_t vid, uint16_t pid) = 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 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 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 int getType() = 0;
virtual uint8_t getSerialIntf(int index) { return m_serialIntfMap[index]; } virtual uint8_t getSerialIntf(int index) { return m_serialIntfMap[index]; }

View File

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

View File

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

View File

@ -18,7 +18,7 @@
#if USBHOST_KEYBOARD #if USBHOST_KEYBOARD
static uint8_t keymap[4][0x39] = { static uint8_t keymap[4][0x39] = {
{ 0, 0, 0, 0, 'a', 'b' /*0x05*/, { 0, 0, 0, 0, 'a', 'b' /*0x05*/,
'c', 'd', 'e', 'f', 'g' /*0x0a*/, 'c', 'd', 'e', 'f', 'g' /*0x0a*/,
'h', 'i', 'j', 'k', 'l'/*0x0f*/, 'h', 'i', 'j', 'k', 'l'/*0x0f*/,
@ -100,30 +100,30 @@ bool USBHostKeyboard::connected() {
bool USBHostKeyboard::connect() { bool USBHostKeyboard::connect() {
if (dev_connected) { if (dev_connected) {
return true; return true;
} }
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) { if ((dev = host->getDevice(i)) != NULL) {
if (host->enumerate(dev, this)) if (host->enumerate(dev, this))
break; break;
if (keyboard_device_found) { if (keyboard_device_found) {
int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN); int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN);
if (!int_in) if (!int_in)
break; break;
USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf); USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf);
dev->setName("Keyboard", keyboard_intf); dev->setName("Keyboard", keyboard_intf);
host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init); host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init);
int_in->attach(this, &USBHostKeyboard::rxHandler); int_in->attach(this, &USBHostKeyboard::rxHandler);
host->interruptRead(dev, int_in, report, int_in->getSize(), false); host->interruptRead(dev, int_in, report, int_in->getSize(), false);
dev_connected = true; dev_connected = true;
return true; return true;
} }

View File

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

View File

@ -35,7 +35,7 @@ void USBHostMouse::init() {
dev_connected = false; dev_connected = false;
mouse_device_found = false; mouse_device_found = false;
mouse_intf = -1; mouse_intf = -1;
buttons = 0; buttons = 0;
x = 0; x = 0;
y = 0; y = 0;
@ -51,26 +51,26 @@ bool USBHostMouse::connect() {
if (dev_connected) { if (dev_connected) {
return true; return true;
} }
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) { if ((dev = host->getDevice(i)) != NULL) {
if(host->enumerate(dev, this)) if(host->enumerate(dev, this))
break; break;
if (mouse_device_found) { if (mouse_device_found) {
int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN); int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN);
if (!int_in) if (!int_in)
break; break;
USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf); USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf);
dev->setName("Mouse", mouse_intf); dev->setName("Mouse", mouse_intf);
host->registerDriver(dev, mouse_intf, this, &USBHostMouse::init); host->registerDriver(dev, mouse_intf, this, &USBHostMouse::init);
int_in->attach(this, &USBHostMouse::rxHandler); int_in->attach(this, &USBHostMouse::rxHandler);
host->interruptRead(dev, int_in, report, int_in->getSize(), false); host->interruptRead(dev, int_in, report, int_in->getSize(), false);
dev_connected = true; dev_connected = true;
return true; return true;
} }
@ -82,33 +82,33 @@ bool USBHostMouse::connect() {
void USBHostMouse::rxHandler() { void USBHostMouse::rxHandler() {
int len_listen = int_in->getSize(); int len_listen = int_in->getSize();
if (onUpdate) { if (onUpdate) {
(*onUpdate)(report[0] & 0x07, report[1], report[2], report[3]); (*onUpdate)(report[0] & 0x07, report[1], report[2], report[3]);
} }
if (onButtonUpdate && (buttons != (report[0] & 0x07))) { if (onButtonUpdate && (buttons != (report[0] & 0x07))) {
(*onButtonUpdate)(report[0] & 0x07); (*onButtonUpdate)(report[0] & 0x07);
} }
if (onXUpdate && (x != report[1])) { if (onXUpdate && (x != report[1])) {
(*onXUpdate)(report[1]); (*onXUpdate)(report[1]);
} }
if (onYUpdate && (y != report[2])) { if (onYUpdate && (y != report[2])) {
(*onYUpdate)(report[2]); (*onYUpdate)(report[2]);
} }
if (onZUpdate && (z != report[3])) { if (onZUpdate && (z != report[3])) {
(*onZUpdate)(report[3]); (*onZUpdate)(report[3]);
} }
// update mouse state // update mouse state
buttons = report[0] & 0x07; buttons = report[0] & 0x07;
x = report[1]; x = report[1];
y = report[2]; y = report[2];
z = report[3]; z = report[3];
if (dev) if (dev)
host->interruptRead(dev, int_in, report, len_listen, false); host->interruptRead(dev, int_in, report, len_listen, false);
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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