mirror of https://github.com/ARMmbed/mbed-os.git
spaces removal - USBHost
parent
9017b27778
commit
081230ee9c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) ;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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];
|
||||||
};
|
};
|
||||||
|
|
|
@ -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]; }
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue