mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-22 08:22:04 +03:00
USBHost library to new format
This commit is contained in:
40
libraries/USBHost/src/KeyboardController.cpp
Normal file
40
libraries/USBHost/src/KeyboardController.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright (c) 2012 Arduino. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <KeyboardController.h>
|
||||
|
||||
extern "C" {
|
||||
void __keyboardControllerEmptyCallback() { }
|
||||
}
|
||||
|
||||
void keyPressed() __attribute__ ((weak, alias("__keyboardControllerEmptyCallback")));
|
||||
void keyReleased() __attribute__ ((weak, alias("__keyboardControllerEmptyCallback")));
|
||||
|
||||
void KeyboardController::OnKeyDown(uint8_t _mod, uint8_t _oemKey) {
|
||||
modifiers = _mod;
|
||||
keyOem = _oemKey;
|
||||
key = OemToAscii(_mod, _oemKey);
|
||||
keyPressed();
|
||||
}
|
||||
|
||||
void KeyboardController::OnKeyUp(uint8_t _mod, uint8_t _oemKey) {
|
||||
modifiers = _mod;
|
||||
keyOem = _oemKey;
|
||||
key = OemToAscii(_mod, _oemKey);
|
||||
keyReleased();
|
||||
}
|
54
libraries/USBHost/src/KeyboardController.h
Normal file
54
libraries/USBHost/src/KeyboardController.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (c) 2012 Arduino. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef KEYBOARD_CONTROLLER_H
|
||||
#define KEYBOARD_CONTROLLER_H
|
||||
|
||||
#include <hidboot.h>
|
||||
|
||||
enum KeyboardModifiers {
|
||||
LeftCtrl = 1,
|
||||
LeftShift = 2,
|
||||
Alt = 4,
|
||||
LeftCmd = 8,
|
||||
RightCtrl = 16,
|
||||
RightShift = 32,
|
||||
AltGr = 64,
|
||||
RightCmd = 128
|
||||
};
|
||||
|
||||
class KeyboardController : public KeyboardReportParser {
|
||||
public:
|
||||
KeyboardController(USBHost &usb) : hostKeyboard(&usb), key(0), keyOem(0), modifiers(0) {
|
||||
hostKeyboard.SetReportParser(0, this);
|
||||
};
|
||||
|
||||
uint8_t getKey() { return key; };
|
||||
uint8_t getModifiers() { return modifiers; };
|
||||
uint8_t getOemKey() { return keyOem; };
|
||||
|
||||
protected:
|
||||
virtual void OnKeyDown(uint8_t mod, uint8_t key);
|
||||
virtual void OnKeyUp(uint8_t mod, uint8_t key);
|
||||
|
||||
private:
|
||||
HIDBoot<HID_PROTOCOL_KEYBOARD> hostKeyboard;
|
||||
uint8_t key, keyOem, modifiers;
|
||||
};
|
||||
|
||||
#endif
|
83
libraries/USBHost/src/MouseController.cpp
Normal file
83
libraries/USBHost/src/MouseController.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright (c) 2012 Arduino. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <MouseController.h>
|
||||
|
||||
extern "C" {
|
||||
void __mouseControllerEmptyCallback() { }
|
||||
}
|
||||
|
||||
void mouseClicked() __attribute__ ((weak, alias("__mouseControllerEmptyCallback")));
|
||||
void mouseDragged() __attribute__ ((weak, alias("__mouseControllerEmptyCallback")));
|
||||
void mouseMoved() __attribute__ ((weak, alias("__mouseControllerEmptyCallback")));
|
||||
void mousePressed() __attribute__ ((weak, alias("__mouseControllerEmptyCallback")));
|
||||
void mouseReleased() __attribute__ ((weak, alias("__mouseControllerEmptyCallback")));
|
||||
|
||||
int MouseController::getXChange() {
|
||||
int r = dx;
|
||||
dx = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
int MouseController::getYChange() {
|
||||
int r = dy;
|
||||
dy = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
void MouseController::OnMouseMove(MOUSEINFO *mi) {
|
||||
dx += mi->dX;
|
||||
dy += mi->dY;
|
||||
if (buttons != 0)
|
||||
mouseDragged();
|
||||
else
|
||||
mouseMoved();
|
||||
}
|
||||
|
||||
void MouseController::OnLeftButtonUp(MOUSEINFO *mi) {
|
||||
buttons &= ~LEFT_BUTTON;
|
||||
mouseReleased();
|
||||
mouseClicked();
|
||||
}
|
||||
|
||||
void MouseController::OnLeftButtonDown(MOUSEINFO *mi) {
|
||||
buttons |= LEFT_BUTTON;
|
||||
mousePressed();
|
||||
}
|
||||
|
||||
void MouseController::OnMiddleButtonUp(MOUSEINFO *mi) {
|
||||
buttons &= ~MIDDLE_BUTTON;
|
||||
mouseReleased();
|
||||
mouseClicked();
|
||||
}
|
||||
|
||||
void MouseController::OnMiddleButtonDown(MOUSEINFO *mi) {
|
||||
buttons |= MIDDLE_BUTTON;
|
||||
mousePressed();
|
||||
}
|
||||
|
||||
void MouseController::OnRightButtonUp(MOUSEINFO *mi) {
|
||||
buttons &= ~RIGHT_BUTTON;
|
||||
mouseReleased();
|
||||
mouseClicked();
|
||||
}
|
||||
|
||||
void MouseController::OnRightButtonDown(MOUSEINFO *mi) {
|
||||
buttons |= RIGHT_BUTTON;
|
||||
mousePressed();
|
||||
}
|
57
libraries/USBHost/src/MouseController.h
Normal file
57
libraries/USBHost/src/MouseController.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
Copyright (c) 2012 Arduino. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MOUSE_CONTROLLER_H
|
||||
#define MOUSE_CONTROLLER_H
|
||||
|
||||
#include <hidboot.h>
|
||||
|
||||
enum MouseButton {
|
||||
LEFT_BUTTON = 0x01,
|
||||
MIDDLE_BUTTON = 0x02,
|
||||
RIGHT_BUTTON = 0x04
|
||||
};
|
||||
|
||||
class MouseController : public MouseReportParser
|
||||
{
|
||||
public:
|
||||
MouseController(USBHost &usb) : hostMouse(&usb), dx(0), dy(0), buttons(0) {
|
||||
hostMouse.SetReportParser(0, this);
|
||||
};
|
||||
|
||||
bool getButton(MouseButton button) { return (buttons & button) == button; };
|
||||
int getXChange();
|
||||
int getYChange();
|
||||
// int getWheelChange(); // Not implemented
|
||||
|
||||
protected:
|
||||
virtual void OnMouseMove(MOUSEINFO *mi);
|
||||
virtual void OnLeftButtonUp(MOUSEINFO *mi);
|
||||
virtual void OnLeftButtonDown(MOUSEINFO *mi);
|
||||
virtual void OnMiddleButtonUp(MOUSEINFO *mi);
|
||||
virtual void OnMiddleButtonDown(MOUSEINFO *mi);
|
||||
virtual void OnRightButtonUp(MOUSEINFO *mi);
|
||||
virtual void OnRightButtonDown(MOUSEINFO *mi);
|
||||
|
||||
private:
|
||||
HIDBoot<HID_PROTOCOL_MOUSE> hostMouse;
|
||||
int dx, dy;
|
||||
int buttons;
|
||||
};
|
||||
|
||||
#endif
|
856
libraries/USBHost/src/Usb.cpp
Normal file
856
libraries/USBHost/src/Usb.cpp
Normal file
@ -0,0 +1,856 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
/* USB functions */
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Usb.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static uint32_t usb_error = 0;
|
||||
static uint32_t usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
|
||||
|
||||
/**
|
||||
* \brief USBHost class constructor.
|
||||
*/
|
||||
USBHost::USBHost() : bmHubPre(0)
|
||||
{
|
||||
// Set up state machine
|
||||
usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
|
||||
|
||||
// Init host stack
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize USBHost class.
|
||||
*/
|
||||
void USBHost::init()
|
||||
{
|
||||
devConfigIndex = 0;
|
||||
bmHubPre = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get USBHost state.
|
||||
*
|
||||
* \return USB enumeration status (see USBHost::task).
|
||||
*/
|
||||
uint32_t USBHost::getUsbTaskState(void)
|
||||
{
|
||||
return (usb_task_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set USB state.
|
||||
*
|
||||
* \param state New USBHost status to be set.
|
||||
*/
|
||||
void USBHost::setUsbTaskState(uint32_t state)
|
||||
{
|
||||
usb_task_state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get endpoint info from USB device address and device endpoint.
|
||||
*
|
||||
* \note This function should be used to know which host pipe is being used for
|
||||
* the corresponding device endpoint.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
* \param ep USB device endpoint number.
|
||||
*
|
||||
* \return Pointer to an EpInfo structure.
|
||||
*/
|
||||
EpInfo* USBHost::getEpInfoEntry(uint32_t addr, uint32_t ep)
|
||||
{
|
||||
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
||||
|
||||
if (!p || !p->epinfo)
|
||||
return NULL;
|
||||
|
||||
EpInfo *pep = p->epinfo;
|
||||
|
||||
for (uint32_t i = 0; i < p->epcount; i++)
|
||||
{
|
||||
if (pep->deviceEpNum == ep)
|
||||
return pep;
|
||||
|
||||
pep++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set device endpoint entry.
|
||||
*
|
||||
* \note Each device is different and has a different number of endpoints.
|
||||
* This function sets endpoint record structure to the device using address
|
||||
* addr in the address pool.
|
||||
*
|
||||
* \param ul_pipe Pipe address.
|
||||
* \param ul_token_type Token type.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL device not found.
|
||||
*/
|
||||
uint32_t USBHost::setEpInfoEntry(uint32_t addr, uint32_t epcount, EpInfo* eprecord_ptr)
|
||||
{
|
||||
if (!eprecord_ptr)
|
||||
return USB_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
||||
|
||||
if (!p)
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
|
||||
p->address = addr;
|
||||
p->epinfo = eprecord_ptr;
|
||||
p->epcount = epcount;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set host pipe target address and set ppep pointer to the endpoint
|
||||
* structure matching the specified USB device address and endpoint.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
* \param ep USB device endpoint number.
|
||||
* \param ppep Endpoint info structure pointer set by setPipeAddress.
|
||||
* \param nak_limit Maximum number of NAK permitted.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL device not found.
|
||||
* \retval USB_ERROR_EPINFO_IS_NULL no endpoint structure found for this device.
|
||||
* \retval USB_ERROR_EP_NOT_FOUND_IN_TBL the specified device endpoint cannot be found.
|
||||
*/
|
||||
uint32_t USBHost::setPipeAddress(uint32_t addr, uint32_t ep, EpInfo **ppep, uint32_t &nak_limit)
|
||||
{
|
||||
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
||||
|
||||
if (!p)
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
|
||||
if (!p->epinfo)
|
||||
return USB_ERROR_EPINFO_IS_NULL;
|
||||
|
||||
*ppep = getEpInfoEntry(addr, ep);
|
||||
|
||||
if (!*ppep)
|
||||
return USB_ERROR_EP_NOT_FOUND_IN_TBL;
|
||||
|
||||
nak_limit = (0x0001UL << (((*ppep)->bmNakPower > USB_NAK_MAX_POWER ) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower));
|
||||
nak_limit--;
|
||||
|
||||
// Set peripheral address
|
||||
TRACE_USBHOST(printf(" => SetAddress deviceEP=%lu configued as hostPIPE=%lu sending to address=%lu\r\n", ep, (*ppep)->hostPipeNum, addr);)
|
||||
uhd_configure_address((*ppep)->hostPipeNum, addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Send a control request.
|
||||
* Sets address, endpoint, fills control packet with necessary data, dispatches
|
||||
* control packet, and initiates bulk IN transfer depending on request.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
* \param ep USB device endpoint number.
|
||||
* \param bmReqType Request direction.
|
||||
* \param bRequest Request type.
|
||||
* \param wValLo Value low.
|
||||
* \param wValHi Value high.
|
||||
* \param wInd Index field.
|
||||
* \param total Request length.
|
||||
* \param nbytes Number of bytes to read.
|
||||
* \param dataptr Data pointer.
|
||||
* \param p USB class reader.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::ctrlReq(uint32_t addr, uint32_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, uint16_t wInd, uint16_t total, uint32_t nbytes, uint8_t* dataptr, USBReadParser *p)
|
||||
{
|
||||
// Request direction, IN or OUT
|
||||
uint32_t direction = 0;
|
||||
uint32_t rcode = 0;
|
||||
SETUP_PKT setup_pkt;
|
||||
|
||||
EpInfo *pep = 0;
|
||||
uint32_t nak_limit;
|
||||
|
||||
TRACE_USBHOST(printf(" => ctrlReq\r\n");)
|
||||
|
||||
// Set peripheral address
|
||||
rcode = setPipeAddress(addr, ep, &pep, nak_limit);
|
||||
if (rcode)
|
||||
return rcode;
|
||||
|
||||
// Allocate Pipe0 with default 64 bytes size if not already initialized
|
||||
// TODO : perform a get device descriptor first to get device endpoint size (else data can be missed if device ep0 > host pipe0)
|
||||
rcode = UHD_Pipe0_Alloc(0, 64);
|
||||
if (rcode)
|
||||
{
|
||||
TRACE_USBHOST(printf("/!\\ USBHost::ctrlReq : EP0 allocation error: %lu\r\n", rcode);)
|
||||
return (rcode);
|
||||
}
|
||||
|
||||
// Determine request direction
|
||||
direction = ((bmReqType & 0x80 ) > 0);
|
||||
|
||||
// Fill in setup packet
|
||||
setup_pkt.ReqType_u.bmRequestType = bmReqType;
|
||||
setup_pkt.bRequest = bRequest;
|
||||
setup_pkt.wVal_u.wValueLo = wValLo;
|
||||
setup_pkt.wVal_u.wValueHi = wValHi;
|
||||
setup_pkt.wIndex = wInd;
|
||||
setup_pkt.wLength = total;
|
||||
|
||||
// Configure and write the setup packet into the FIFO
|
||||
uhd_configure_pipe_token(0, tokSETUP);
|
||||
UHD_Pipe_Write(pep->hostPipeNum, 8, (uint8_t *)&setup_pkt);
|
||||
|
||||
// Dispatch packet
|
||||
rcode = dispatchPkt(tokSETUP, pep->hostPipeNum, nak_limit);
|
||||
if (rcode)
|
||||
{
|
||||
// Return HRSLT if not zero
|
||||
TRACE_USBHOST(printf("/!\\ USBHost::ctrlReq : Setup packet error: %lu\r\n", rcode);)
|
||||
return (rcode);
|
||||
}
|
||||
|
||||
// Data stage (if present)
|
||||
if (dataptr != 0)
|
||||
{
|
||||
if (direction)
|
||||
{
|
||||
// IN transfer
|
||||
TRACE_USBHOST(printf(" => ctrlData IN\r\n");)
|
||||
uint32_t left = total;
|
||||
|
||||
while (left)
|
||||
{
|
||||
// Bytes read into buffer
|
||||
uint32_t read = nbytes;
|
||||
|
||||
rcode = InTransfer(pep, nak_limit, &read, dataptr);
|
||||
if (rcode)
|
||||
return rcode;
|
||||
|
||||
// Invoke callback function if inTransfer completed successfuly and callback function pointer is specified
|
||||
if (!rcode && p)
|
||||
((USBReadParser*)p)->Parse(read, dataptr, total - left);
|
||||
|
||||
left -= read;
|
||||
|
||||
if (read < nbytes)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// OUT transfer
|
||||
TRACE_USBHOST(printf(" => ctrlData OUT\r\n");)
|
||||
rcode = OutTransfer(pep, nak_limit, nbytes, dataptr);
|
||||
}
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
TRACE_USBHOST(printf("/!\\ USBHost::ctrlData : Data packet error: %lu\r\n", rcode);)
|
||||
return (rcode);
|
||||
}
|
||||
}
|
||||
|
||||
// Status stage
|
||||
return dispatchPkt((direction) ? tokOUTHS : tokINHS, pep->hostPipeNum, nak_limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Perform IN request to the specified USB device.
|
||||
*
|
||||
* \note This function handles multiple packets (if necessary) and can
|
||||
* receive a maximum of 'nbytesptr' bytes. It keep sending INs and writes data
|
||||
* to memory area pointed by 'data'. The actual amount of received bytes is
|
||||
* stored in 'nbytesptr'.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
* \param ep USB device endpoint number.
|
||||
* \param nbytesptr Receive buffer size. It is set to the amount of received
|
||||
* bytes when the function returns.
|
||||
* \param data Buffer to store received data.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::inTransfer(uint32_t addr, uint32_t ep, uint32_t *nbytesptr, uint8_t* data)
|
||||
{
|
||||
EpInfo *pep = NULL;
|
||||
uint32_t nak_limit = 0;
|
||||
|
||||
uint32_t rcode = setPipeAddress(addr, ep, &pep, nak_limit);
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
return rcode;
|
||||
}
|
||||
|
||||
return InTransfer(pep, nak_limit, nbytesptr, data);
|
||||
}
|
||||
|
||||
uint32_t USBHost::InTransfer(EpInfo *pep, uint32_t nak_limit, uint32_t *nbytesptr, uint8_t* data)
|
||||
{
|
||||
uint32_t rcode = 0;
|
||||
uint32_t pktsize = 0;
|
||||
uint32_t nbytes = *nbytesptr;
|
||||
uint32_t maxpktsize = pep->maxPktSize;
|
||||
|
||||
*nbytesptr = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Use a 'return' to exit this loop
|
||||
// IN packet to EP-'endpoint'. Function takes care of NAKS.
|
||||
rcode = dispatchPkt(tokIN, pep->hostPipeNum, nak_limit);
|
||||
if (rcode)
|
||||
{
|
||||
if (rcode == 1)
|
||||
{
|
||||
// Pipe freeze is mandatory to avoid sending IN endlessly (else reception becomes messy then)
|
||||
uhd_freeze_pipe(pep->hostPipeNum);
|
||||
}
|
||||
// Should be 1, indicating NAK. Else return error code.
|
||||
return rcode;
|
||||
}
|
||||
|
||||
// Number of received bytes
|
||||
pktsize = uhd_byte_count(pep->hostPipeNum);
|
||||
if (nbytes < pktsize)
|
||||
{
|
||||
TRACE_USBHOST(printf("/!\\ USBHost::InTransfer : receive buffer is too small, size=%lu, expected=%lu\r\n", nbytes, pktsize);)
|
||||
}
|
||||
data += UHD_Pipe_Read(pep->hostPipeNum, pktsize, data);
|
||||
|
||||
// Add this packet's byte count to total transfer length
|
||||
*nbytesptr += pktsize;
|
||||
|
||||
// The transfer is complete under two conditions:
|
||||
// 1. The device sent a short packet (L.T. maxPacketSize)
|
||||
// 2. 'nbytes' have been transferred.
|
||||
if ((pktsize < maxpktsize) || (*nbytesptr >= nbytes))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Perform OUT request to the specified USB device.
|
||||
*
|
||||
* \note This function handles multiple packets (if necessary) and sends
|
||||
* 'nbytes' bytes.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
* \param ep USB device endpoint number.
|
||||
* \param nbytes Buffer size to be sent.
|
||||
* \param data Buffer to send.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::outTransfer(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* data)
|
||||
{
|
||||
EpInfo *pep = NULL;
|
||||
uint32_t nak_limit = 0;
|
||||
|
||||
uint32_t rcode = setPipeAddress(addr, ep, &pep, nak_limit);
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
return rcode;
|
||||
}
|
||||
|
||||
return OutTransfer(pep, nak_limit, nbytes, data);
|
||||
}
|
||||
|
||||
uint32_t USBHost::OutTransfer(EpInfo *pep, uint32_t nak_limit, uint32_t nbytes, uint8_t *data)
|
||||
{
|
||||
uint32_t rcode = 0;
|
||||
uint32_t bytes_tosend = 0;
|
||||
uint32_t bytes_left = nbytes;
|
||||
uint32_t maxpktsize = pep->maxPktSize;
|
||||
|
||||
if (maxpktsize < 1)
|
||||
return USB_ERROR_INVALID_MAX_PKT_SIZE;
|
||||
|
||||
while (bytes_left)
|
||||
{
|
||||
bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left;
|
||||
|
||||
// Write FIFO
|
||||
UHD_Pipe_Write(pep->hostPipeNum, bytes_tosend, data);
|
||||
|
||||
// Use a 'return' to exit this loop
|
||||
// OUT packet to EP-'endpoint'. Function takes care of NAKS.
|
||||
rcode = dispatchPkt(tokOUT, pep->hostPipeNum, nak_limit);
|
||||
if (rcode)
|
||||
{
|
||||
// Should be 0, indicating ACK. Else return error code.
|
||||
return rcode;
|
||||
}
|
||||
|
||||
bytes_left -= bytes_tosend;
|
||||
data += bytes_tosend;
|
||||
}
|
||||
|
||||
// Should be 0 in all cases
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dispatch USB packet.
|
||||
*
|
||||
* \note Ensure peripheral address is set and relevant buffer is loaded/empty.
|
||||
* If NAK, tries to re-send up to nak_limit times.
|
||||
* If nak_limit == 0, do not count NAKs, exit after timeout.
|
||||
*
|
||||
* \param token Token type (Setup, In or Out).
|
||||
* \param hostPipeNum Host pipe number to use for sending USB packet.
|
||||
* \param nak_limit Maximum number of NAK permitted.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::dispatchPkt(uint32_t token, uint32_t hostPipeNum, uint32_t nak_limit)
|
||||
{
|
||||
uint32_t timeout = millis() + USB_XFER_TIMEOUT;
|
||||
uint32_t nak_count = 0;
|
||||
uint32_t rcode = USB_ERROR_TRANSFER_TIMEOUT;
|
||||
|
||||
TRACE_USBHOST(printf(" => dispatchPkt token=%lu pipe=%lu nak_limit=%lu\r\n", token, hostPipeNum, nak_limit);)
|
||||
|
||||
// Launch the transfer
|
||||
UHD_Pipe_Send(hostPipeNum, token);
|
||||
|
||||
// Check timeout but don't hold timeout if VBUS is lost
|
||||
while ((timeout > millis()) && (UHD_GetVBUSState() == UHD_STATE_CONNECTED))
|
||||
{
|
||||
// Wait for transfer completion
|
||||
if (UHD_Pipe_Is_Transfer_Complete(hostPipeNum, token))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Is NAK received?
|
||||
if (Is_uhd_nak_received(hostPipeNum))
|
||||
{
|
||||
uhd_ack_nak_received(hostPipeNum);
|
||||
nak_count++;
|
||||
|
||||
if (nak_limit && (nak_count == nak_limit))
|
||||
{
|
||||
// Return NAK
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure device using known device classes.
|
||||
* The device get a new address even if its class remain unknown.
|
||||
*
|
||||
* \param parent USB device address of the device's parent (0 if root).
|
||||
* \param port USB device base address (see AddressPoolImpl).
|
||||
* \param lowspeed Device speed.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::Configuring(uint32_t parent, uint32_t port, uint32_t lowspeed)
|
||||
{
|
||||
uint32_t rcode = 0;
|
||||
|
||||
for (; devConfigIndex < USB_NUMDEVICES; ++devConfigIndex)
|
||||
{
|
||||
if (!devConfig[devConfigIndex])
|
||||
continue;
|
||||
|
||||
rcode = devConfig[devConfigIndex]->Init(parent, port, lowspeed);
|
||||
|
||||
if (!rcode)
|
||||
{
|
||||
TRACE_USBHOST(printf("USBHost::Configuring : found device class!\r\n");)
|
||||
devConfigIndex = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED)
|
||||
{
|
||||
TRACE_USBHOST(printf("USBHost::Configuring : ERROR : device not supported!\r\n");)
|
||||
}
|
||||
else if (rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)
|
||||
{
|
||||
TRACE_USBHOST(printf("USBHost::Configuring : ERROR : class instance already in use!\r\n");)
|
||||
}
|
||||
else
|
||||
{
|
||||
// in case of an error devConfigIndex should be reset to 0
|
||||
// in order to start from the very beginning the next time
|
||||
// the program gets here
|
||||
if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE)
|
||||
devConfigIndex = 0;
|
||||
|
||||
return rcode;
|
||||
}
|
||||
}
|
||||
|
||||
// Device class is not supported by any of the registered classes
|
||||
devConfigIndex = 0;
|
||||
|
||||
rcode = DefaultAddressing(parent, port, lowspeed);
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure device with unknown USB class.
|
||||
*
|
||||
* \param parent USB device address of the device's parent (0 if root).
|
||||
* \param port USB device base address (see AddressPoolImpl).
|
||||
* \param lowspeed Device speed.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::DefaultAddressing(uint32_t parent, uint32_t port, uint32_t lowspeed)
|
||||
{
|
||||
uint32_t rcode = 0;
|
||||
UsbDevice *p0 = 0, *p = 0;
|
||||
|
||||
// Get pointer to pseudo device with address 0 assigned
|
||||
p0 = addrPool.GetUsbDevicePtr(0);
|
||||
|
||||
if (!p0)
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
|
||||
if (!p0->epinfo)
|
||||
return USB_ERROR_EPINFO_IS_NULL;
|
||||
|
||||
p0->lowspeed = (lowspeed) ? 1 : 0;
|
||||
|
||||
// Allocate new address according to device class
|
||||
uint32_t bAddress = addrPool.AllocAddress(parent, 0, port);
|
||||
|
||||
if (!bAddress)
|
||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||
|
||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||
|
||||
if (!p)
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
|
||||
p->lowspeed = lowspeed;
|
||||
|
||||
// Assign new address to the device
|
||||
rcode = setAddr(0, 0, bAddress);
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
TRACE_USBHOST(printf("/!\\ USBHost::DefaultAddressing : Set address failed with code: %lu\r\n", rcode);)
|
||||
addrPool.FreeAddress(bAddress);
|
||||
bAddress = 0;
|
||||
return rcode;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Release device and free associated resources.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::ReleaseDevice(uint32_t addr)
|
||||
{
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
for (uint32_t i = 0; i < USB_NUMDEVICES; ++i)
|
||||
{
|
||||
if (devConfig[i]->GetAddress() == addr)
|
||||
{
|
||||
return devConfig[i]->Release();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get device descriptor.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
* \param ep USB device endpoint number.
|
||||
* \param nbytes Buffer size.
|
||||
* \param dataptr Buffer to store received descriptor.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::getDevDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* dataptr)
|
||||
{
|
||||
return (ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, nbytes, dataptr, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get configuration descriptor.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
* \param ep USB device endpoint number.
|
||||
* \param nbytes Buffer size.
|
||||
* \param conf Configuration number.
|
||||
* \param dataptr Buffer to store received descriptor.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::getConfDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint32_t conf, uint8_t* dataptr)
|
||||
{
|
||||
return (ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, nbytes, dataptr, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get configuration descriptor and extract endpoints using USBReadParser object.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
* \param ep USB device endpoint number.
|
||||
* \param conf Configuration number.
|
||||
* \param p USBReadParser object pointer used to extract endpoints.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::getConfDescr(uint32_t addr, uint32_t ep, uint32_t conf, USBReadParser *p)
|
||||
{
|
||||
const uint32_t bufSize = 64;
|
||||
uint8_t buf[bufSize];
|
||||
|
||||
uint32_t ret = getConfDescr(addr, ep, 8, conf, buf);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
uint32_t total = ((USB_CONFIGURATION_DESCRIPTOR*)buf)->wTotalLength;
|
||||
delay(100);
|
||||
|
||||
return (ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, total, bufSize, buf, p));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get string descriptor.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
* \param ep USB device endpoint number.
|
||||
* \param nbytes Buffer size.
|
||||
* \param index String index.
|
||||
* \param langid Language ID.
|
||||
* \param dataptr Buffer to store received descriptor.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::getStrDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t index, uint16_t langid, uint8_t* dataptr)
|
||||
{
|
||||
return (ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nbytes, nbytes, dataptr, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set USB device address.
|
||||
*
|
||||
* \param oldaddr Current USB device address.
|
||||
* \param ep USB device endpoint number.
|
||||
* \param addr New USB device address to be set.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::setAddr(uint32_t oldaddr, uint32_t ep, uint32_t newaddr)
|
||||
{
|
||||
TRACE_USBHOST(printf(" => USBHost::setAddr\r\n");)
|
||||
return ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set configuration.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
* \param ep USB device endpoint number.
|
||||
* \param conf_value New configuration value to be set.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t USBHost::setConf(uint32_t addr, uint32_t ep, uint32_t conf_value)
|
||||
{
|
||||
return (ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0x0000, 0, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief USB main task, responsible for enumeration and clean up stage.
|
||||
*
|
||||
* \note Must be periodically called from loop().
|
||||
*/
|
||||
void USBHost::Task(void)
|
||||
{
|
||||
uint32_t rcode = 0;
|
||||
volatile uint32_t tmpdata = 0;
|
||||
static uint32_t delay = 0;
|
||||
uint32_t lowspeed = 0;
|
||||
|
||||
// Update USB task state on Vbus change
|
||||
tmpdata = UHD_GetVBUSState();
|
||||
switch (tmpdata)
|
||||
{
|
||||
case UHD_STATE_ERROR:
|
||||
// Illegal state
|
||||
usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
|
||||
lowspeed = 0;
|
||||
break;
|
||||
|
||||
case UHD_STATE_DISCONNECTED:
|
||||
// Disconnected state
|
||||
if ((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED)
|
||||
{
|
||||
usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
|
||||
lowspeed = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case UHD_STATE_CONNECTED:
|
||||
// Attached state
|
||||
if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED)
|
||||
{
|
||||
delay = millis() + USB_SETTLE_DELAY;
|
||||
usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
|
||||
//FIXME TODO: lowspeed = 0 ou 1; already done by hardware?
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Poll connected devices (if required)
|
||||
for (uint32_t i = 0; i < USB_NUMDEVICES; ++i)
|
||||
if (devConfig[i])
|
||||
rcode = devConfig[i]->Poll();
|
||||
|
||||
// Perform USB enumeration stage and clean up
|
||||
switch (usb_task_state)
|
||||
{
|
||||
case USB_DETACHED_SUBSTATE_INITIALIZE:
|
||||
TRACE_USBHOST(printf(" + USB_DETACHED_SUBSTATE_INITIALIZE\r\n");)
|
||||
|
||||
// Init USB stack and driver
|
||||
UHD_Init();
|
||||
init();
|
||||
|
||||
// Free all USB resources
|
||||
for (uint32_t i = 0; i < USB_NUMDEVICES; ++i)
|
||||
if (devConfig[i])
|
||||
rcode = devConfig[i]->Release();
|
||||
|
||||
usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
|
||||
break;
|
||||
|
||||
case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE:
|
||||
// Nothing to do
|
||||
break;
|
||||
|
||||
case USB_DETACHED_SUBSTATE_ILLEGAL:
|
||||
// Nothing to do
|
||||
break;
|
||||
|
||||
case USB_ATTACHED_SUBSTATE_SETTLE:
|
||||
// Settle time for just attached device
|
||||
if (delay < millis())
|
||||
{
|
||||
TRACE_USBHOST(printf(" + USB_ATTACHED_SUBSTATE_SETTLE\r\n");)
|
||||
usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
|
||||
TRACE_USBHOST(printf(" + USB_ATTACHED_SUBSTATE_RESET_DEVICE\r\n");)
|
||||
|
||||
// Trigger Bus Reset
|
||||
UHD_BusReset();
|
||||
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
|
||||
break;
|
||||
|
||||
case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
|
||||
if (Is_uhd_reset_sent())
|
||||
{
|
||||
TRACE_USBHOST(printf(" + USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE\r\n");)
|
||||
|
||||
// Clear Bus Reset flag
|
||||
uhd_ack_reset_sent();
|
||||
|
||||
// Enable Start Of Frame generation
|
||||
uhd_enable_sof();
|
||||
|
||||
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
|
||||
|
||||
// Wait 20ms after Bus Reset (USB spec)
|
||||
delay = millis() + 20;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_ATTACHED_SUBSTATE_WAIT_SOF:
|
||||
// Wait for SOF received first
|
||||
if (Is_uhd_sof())
|
||||
{
|
||||
if (delay < millis())
|
||||
{
|
||||
TRACE_USBHOST(printf(" + USB_ATTACHED_SUBSTATE_WAIT_SOF\r\n");)
|
||||
|
||||
// 20ms waiting elapsed
|
||||
usb_task_state = USB_STATE_CONFIGURING;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_STATE_CONFIGURING:
|
||||
TRACE_USBHOST(printf(" + USB_STATE_CONFIGURING\r\n");)
|
||||
rcode = Configuring(0, 0, lowspeed);
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
TRACE_USBHOST(printf("/!\\ USBHost::Task : USB_STATE_CONFIGURING failed with code: %lu\r\n", rcode);)
|
||||
if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE)
|
||||
{
|
||||
usb_error = rcode;
|
||||
usb_task_state = USB_STATE_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
usb_task_state = USB_STATE_RUNNING;
|
||||
TRACE_USBHOST(printf(" + USB_STATE_RUNNING\r\n");)
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_STATE_RUNNING:
|
||||
break;
|
||||
|
||||
case USB_STATE_ERROR:
|
||||
break;
|
||||
}
|
||||
}
|
230
libraries/USBHost/src/Usb.h
Normal file
230
libraries/USBHost/src/Usb.h
Normal file
@ -0,0 +1,230 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
/* USB functions */
|
||||
|
||||
#ifndef USB_H_INCLUDED
|
||||
#define USB_H_INCLUDED
|
||||
|
||||
//#define TRACE_USBHOST(x) x
|
||||
#define TRACE_USBHOST(x)
|
||||
|
||||
#include <stdint.h>
|
||||
#include "usb_ch9.h"
|
||||
#include "address.h"
|
||||
|
||||
/* Common setup data constant combinations */
|
||||
#define bmREQ_GET_DESCR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE // Get descriptor request type
|
||||
#define bmREQ_SET USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE // Set request type for all but 'set feature' and 'set interface'
|
||||
#define bmREQ_CL_GET_INTF USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE // Get interface request type
|
||||
|
||||
// USB Device Classes
|
||||
#define USB_CLASS_USE_CLASS_INFO 0x00 // Use Class Info in the Interface Descriptors
|
||||
#define USB_CLASS_AUDIO 0x01 // Audio
|
||||
#define USB_CLASS_COM_AND_CDC_CTRL 0x02 // Communications and CDC Control
|
||||
#define USB_CLASS_HID 0x03 // HID
|
||||
#define USB_CLASS_PHYSICAL 0x05 // Physical
|
||||
#define USB_CLASS_IMAGE 0x06 // Image
|
||||
#define USB_CLASS_PRINTER 0x07 // Printer
|
||||
#define USB_CLASS_MASS_STORAGE 0x08 // Mass Storage
|
||||
#define USB_CLASS_HUB 0x09 // Hub
|
||||
#define USB_CLASS_CDC_DATA 0x0a // CDC-Data
|
||||
#define USB_CLASS_SMART_CARD 0x0b // Smart-Card
|
||||
#define USB_CLASS_CONTENT_SECURITY 0x0d // Content Security
|
||||
#define USB_CLASS_VIDEO 0x0e // Video
|
||||
#define USB_CLASS_PERSONAL_HEALTH 0x0f // Personal Healthcare
|
||||
#define USB_CLASS_DIAGNOSTIC_DEVICE 0xdc // Diagnostic Device
|
||||
#define USB_CLASS_WIRELESS_CTRL 0xe0 // Wireless Controller
|
||||
#define USB_CLASS_MISC 0xef // Miscellaneous
|
||||
#define USB_CLASS_APP_SPECIFIC 0xfe // Application Specific
|
||||
#define USB_CLASS_VENDOR_SPECIFIC 0xff // Vendor Specific
|
||||
|
||||
// Additional Error Codes
|
||||
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED 0xD1
|
||||
#define USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE 0xD2
|
||||
#define USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS 0xD3
|
||||
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL 0xD4
|
||||
#define USB_ERROR_HUB_ADDRESS_OVERFLOW 0xD5
|
||||
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL 0xD6
|
||||
#define USB_ERROR_EPINFO_IS_NULL 0xD7
|
||||
#define USB_ERROR_INVALID_ARGUMENT 0xD8
|
||||
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD9
|
||||
#define USB_ERROR_INVALID_MAX_PKT_SIZE 0xDA
|
||||
#define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDB
|
||||
#define USB_ERROR_TRANSFER_TIMEOUT 0xFF
|
||||
|
||||
#define USB_XFER_TIMEOUT 5000 //USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec
|
||||
//#define USB_NAK_LIMIT 32000 //NAK limit for a transfer. 0 means NAKs are not counted
|
||||
#define USB_RETRY_LIMIT 3 //retry limit for a transfer
|
||||
#define USB_SETTLE_DELAY 200 //settle delay in milliseconds
|
||||
|
||||
#define USB_NUMDEVICES 16 //number of USB devices
|
||||
//#define HUB_MAX_HUBS 7 // maximum number of hubs that can be attached to the host controller
|
||||
#define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms
|
||||
|
||||
/* USB state machine states */
|
||||
#define USB_STATE_MASK 0xf0
|
||||
|
||||
#define USB_STATE_DETACHED 0x10
|
||||
#define USB_DETACHED_SUBSTATE_INITIALIZE 0x11
|
||||
#define USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE 0x12
|
||||
#define USB_DETACHED_SUBSTATE_ILLEGAL 0x13
|
||||
#define USB_ATTACHED_SUBSTATE_SETTLE 0x20
|
||||
#define USB_ATTACHED_SUBSTATE_RESET_DEVICE 0x30
|
||||
#define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE 0x40
|
||||
#define USB_ATTACHED_SUBSTATE_WAIT_SOF 0x50
|
||||
#define USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE 0x60
|
||||
#define USB_STATE_ADDRESSING 0x70
|
||||
#define USB_STATE_CONFIGURING 0x80
|
||||
#define USB_STATE_RUNNING 0x90
|
||||
#define USB_STATE_ERROR 0xa0
|
||||
#define USB_STATE_MASK 0xf0
|
||||
|
||||
// USB Setup Packet Structure
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{ // offset description
|
||||
uint8_t bmRequestType; // 0 Bit-map of request type
|
||||
struct
|
||||
{
|
||||
uint8_t recipient: 5; // Recipient of the request
|
||||
uint8_t type: 2; // Type of request
|
||||
uint8_t direction: 1; // Direction of data X-fer
|
||||
};
|
||||
} ReqType_u;
|
||||
uint8_t bRequest; // 1 Request
|
||||
union
|
||||
{
|
||||
uint16_t wValue; // 2 Depends on bRequest
|
||||
struct
|
||||
{
|
||||
uint8_t wValueLo;
|
||||
uint8_t wValueHi;
|
||||
};
|
||||
} wVal_u;
|
||||
uint16_t wIndex; // 4 Depends on bRequest
|
||||
uint16_t wLength; // 6 Depends on bRequest
|
||||
} SETUP_PKT, *PSETUP_PKT;
|
||||
|
||||
/**
|
||||
* \class USBReadParser
|
||||
*
|
||||
* \brief Base class used for USB descriptor parsing.
|
||||
*/
|
||||
class USBReadParser
|
||||
{
|
||||
public:
|
||||
virtual void Parse(const uint32_t len, const uint8_t *pbuf, const uint32_t &offset) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class USBDeviceConfig
|
||||
*
|
||||
* \brief Device configuration class used for managing device life cycle.
|
||||
*/
|
||||
class USBDeviceConfig
|
||||
{
|
||||
public:
|
||||
//! @brief Perform final enumeration stage.
|
||||
virtual uint32_t Init(uint32_t parent, uint32_t port, uint32_t lowspeed) = 0;
|
||||
|
||||
//! @brief Free USB allocated resources (pipes and address).
|
||||
virtual uint32_t Release() = 0;
|
||||
|
||||
//! @brief Poll USB device. Call is made for each connected USB device on USBHost.task() call.
|
||||
virtual uint32_t Poll() = 0;
|
||||
|
||||
//! @brief Retrieve USB device address.
|
||||
virtual uint32_t GetAddress() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class USBHost
|
||||
*
|
||||
* \brief Main USB host class.
|
||||
*/
|
||||
class USBHost
|
||||
{
|
||||
AddressPoolImpl<USB_NUMDEVICES> addrPool;
|
||||
USBDeviceConfig* devConfig[USB_NUMDEVICES];
|
||||
uint32_t devConfigIndex;
|
||||
uint32_t bmHubPre;
|
||||
|
||||
public:
|
||||
USBHost(void);
|
||||
|
||||
//void SetHubPreMask() { bmHubPre |= bmHUBPRE; };
|
||||
//void ResetHubPreMask() { bmHubPre &= (~bmHUBPRE); };
|
||||
|
||||
AddressPool& GetAddressPool()
|
||||
{
|
||||
return (AddressPool&)addrPool;
|
||||
};
|
||||
|
||||
uint32_t RegisterDeviceClass(USBDeviceConfig *pdev)
|
||||
{
|
||||
for (uint32_t i = 0; i < USB_NUMDEVICES; ++i)
|
||||
{
|
||||
if (!devConfig[i])
|
||||
{
|
||||
devConfig[i] = pdev;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS;
|
||||
};
|
||||
|
||||
void ForEachUsbDevice(UsbDeviceHandleFunc pfunc)
|
||||
{
|
||||
addrPool.ForEachUsbDevice(pfunc);
|
||||
};
|
||||
|
||||
uint32_t getUsbTaskState(void);
|
||||
void setUsbTaskState(uint32_t state);
|
||||
|
||||
EpInfo* getEpInfoEntry(uint32_t addr, uint32_t ep);
|
||||
uint32_t setEpInfoEntry(uint32_t addr, uint32_t epcount, EpInfo* eprecord_ptr);
|
||||
|
||||
/* Control requests */
|
||||
uint32_t getDevDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* dataptr);
|
||||
uint32_t getConfDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint32_t conf, uint8_t* dataptr);
|
||||
uint32_t getConfDescr(uint32_t addr, uint32_t ep, uint32_t conf, USBReadParser *p);
|
||||
uint32_t getStrDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t index, uint16_t langid, uint8_t* dataptr);
|
||||
uint32_t setAddr(uint32_t oldaddr, uint32_t ep, uint32_t newaddr);
|
||||
uint32_t setConf(uint32_t addr, uint32_t ep, uint32_t conf_value);
|
||||
uint32_t ctrlReq(uint32_t addr, uint32_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
|
||||
uint16_t wInd, uint16_t total, uint32_t nbytes, uint8_t* dataptr, USBReadParser *p);
|
||||
|
||||
/* Transfer requests */
|
||||
uint32_t inTransfer(uint32_t addr, uint32_t ep, uint32_t *nbytesptr, uint8_t* data);
|
||||
uint32_t outTransfer(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* data);
|
||||
uint32_t dispatchPkt(uint32_t token, uint32_t ep, uint32_t nak_limit);
|
||||
|
||||
void Task(void);
|
||||
|
||||
uint32_t DefaultAddressing(uint32_t parent, uint32_t port, uint32_t lowspeed);
|
||||
uint32_t Configuring(uint32_t parent, uint32_t port, uint32_t lowspeed);
|
||||
uint32_t ReleaseDevice(uint32_t addr);
|
||||
|
||||
private:
|
||||
void init();
|
||||
uint32_t setPipeAddress(uint32_t addr, uint32_t ep, EpInfo **ppep, uint32_t &nak_limit);
|
||||
uint32_t OutTransfer(EpInfo *pep, uint32_t nak_limit, uint32_t nbytes, uint8_t *data);
|
||||
uint32_t InTransfer(EpInfo *pep, uint32_t nak_limit, uint32_t *nbytesptr, uint8_t* data);
|
||||
};
|
||||
|
||||
#endif /* USB_H_INCLUDED */
|
392
libraries/USBHost/src/address.h
Normal file
392
libraries/USBHost/src/address.h
Normal file
@ -0,0 +1,392 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
#ifndef ADDRESS_H_INCLUDED
|
||||
#define ADDRESS_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* NAK powers. To save space in endpoint data structure, amount of retries before giving up and returning 0x4 is stored in */
|
||||
/* bmNakPower as a power of 2. The actual nak_limit is then calculated as nak_limit = ( 2^bmNakPower - 1) */
|
||||
#define USB_NAK_MAX_POWER 16 //NAK binary order maximum value
|
||||
#define USB_NAK_DEFAULT 14 //default 16K-1 NAKs before giving up
|
||||
#define USB_NAK_NOWAIT 1 //Single NAK stops transfer
|
||||
#define USB_NAK_NONAK 0 //Do not count NAKs, stop retrying after USB Timeout
|
||||
|
||||
/**
|
||||
* \brief Device endpoint definition.
|
||||
*
|
||||
* \note hostPipeNum is the allocated pipe used for the communication with
|
||||
* deviceEpNum remote device endpoint.
|
||||
* There is exactly one hostPipeNum corresponding to a deviceEpNum.
|
||||
*
|
||||
* \note The number of host pipe is limited by the hardware (10 on SAM3X).
|
||||
* Moreover hostPipeNum allocation is static, meaning that only a limited
|
||||
* amount of device endpoints can be opened at the same time, thus limitating
|
||||
* the maximum number of connected devices at the same time.
|
||||
*/
|
||||
struct EpInfo
|
||||
{
|
||||
uint32_t deviceEpNum; // Device endpoint number
|
||||
uint32_t hostPipeNum; // Host corresponding pipe number
|
||||
uint32_t maxPktSize; // Maximum packet size
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t epAttribs;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t bmSndToggle : 1; // Send toggle, when zero bmSNDTOG0, bmSNDTOG1 otherwise
|
||||
uint8_t bmRcvToggle : 1; // Send toggle, when zero bmRCVTOG0, bmRCVTOG1 otherwise
|
||||
uint8_t bmNakPower : 6; // Binary order for NAK_LIMIT value
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief USB device address definition.
|
||||
*
|
||||
* \note The 8 bits USB address is defined like this:
|
||||
*
|
||||
* 7 6 5 4 3 2 1 0
|
||||
* ---------------------------------
|
||||
* | | H | P | P | P | A | A | A |
|
||||
* ---------------------------------
|
||||
*
|
||||
* H - if 1 the address is a hub address
|
||||
* P - parent hub address
|
||||
* A - device address / port number in case of hub
|
||||
*/
|
||||
struct UsbDeviceAddress
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t bmAddress : 3; // device address/port number
|
||||
uint32_t bmParent : 3; // parent hub address
|
||||
uint32_t bmHub : 1; // hub flag
|
||||
uint32_t bmReserved : 25; // reserved, must be zerro
|
||||
};
|
||||
uint32_t devAddress;
|
||||
};
|
||||
};
|
||||
|
||||
#define bmUSB_DEV_ADDR_ADDRESS 0x07
|
||||
#define bmUSB_DEV_ADDR_PARENT 0x38
|
||||
#define bmUSB_DEV_ADDR_HUB 0x40
|
||||
|
||||
/**
|
||||
* \brief USB device definition.
|
||||
*
|
||||
* \note epinfo is used to store the list of device endpoints currently used
|
||||
* by the USBHost stack. This field is set during enumeration process when
|
||||
* a supported USB class is found. See any USB classes implementing
|
||||
* USBDeviceConfig and init() method for reference.
|
||||
*/
|
||||
struct UsbDevice
|
||||
{
|
||||
EpInfo *epinfo; // endpoint info pointer
|
||||
uint32_t address; // address
|
||||
uint32_t epcount; // number of endpoints
|
||||
uint32_t lowspeed; // indicates if a device is the low speed one
|
||||
};
|
||||
|
||||
/**
|
||||
* \class Abstract AddressPool definition.
|
||||
*/
|
||||
class AddressPool
|
||||
{
|
||||
public:
|
||||
virtual UsbDevice* GetUsbDevicePtr(uint32_t addr) = 0;
|
||||
virtual uint32_t AllocAddress(uint32_t parent, uint32_t is_hub = 0, uint32_t port = 0) = 0;
|
||||
virtual void FreeAddress(uint32_t addr) = 0;
|
||||
};
|
||||
|
||||
typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev);
|
||||
|
||||
#define ADDR_ERROR_INVALID_INDEX 0xFF
|
||||
#define ADDR_ERROR_INVALID_ADDRESS 0xFF
|
||||
|
||||
/**
|
||||
* \class AddressPoolImpl definition.
|
||||
* Used to store the list of connected devices and to keep track of free USB
|
||||
* addresses.
|
||||
*/
|
||||
template <const uint32_t MAX_DEVICES_ALLOWED>
|
||||
class AddressPoolImpl : public AddressPool
|
||||
{
|
||||
private:
|
||||
|
||||
EpInfo dev0ep; // Endpoint data structure used during enumeration for uninitialized device
|
||||
|
||||
uint32_t hubCounter; // hub counter is kept
|
||||
// in order to avoid hub address duplication
|
||||
|
||||
UsbDevice thePool[MAX_DEVICES_ALLOWED];
|
||||
|
||||
/**
|
||||
* \brief Initialize the specified address pool entry.
|
||||
*
|
||||
* \param index Index pointing to a UsbDevice instance in the address pool.
|
||||
*/
|
||||
void InitEntry(uint32_t index)
|
||||
{
|
||||
thePool[index].address = 0;
|
||||
thePool[index].epcount = 1;
|
||||
thePool[index].lowspeed = 0;
|
||||
thePool[index].epinfo = &dev0ep;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return an address pool index for a given address. This index can
|
||||
* further be used to retrieve the corresponding USB device instance
|
||||
* UsbDevice.
|
||||
*
|
||||
* \param index Index pointing to a UsbDevice instance in the address pool.
|
||||
*
|
||||
* \return Index number if found, 0 otherwise.
|
||||
* \note Index 0 is reserved for address 0 and shall never be used.
|
||||
*/
|
||||
uint32_t FindAddressIndex(uint32_t address = 0)
|
||||
{
|
||||
for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
|
||||
{
|
||||
if (thePool[i].address == address)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return address pool child index for a given parent. This index can
|
||||
* further be used to retrieve the corresponding USB device instance
|
||||
* UsbDevice.
|
||||
*
|
||||
* \param addr Parent USB address.
|
||||
* \param start Search in the pool from this index. Calling multiple time
|
||||
* this function with the returned index + 1 can be used to walk through
|
||||
* all children.
|
||||
*
|
||||
* \return Child index number if found, 0 otherwise.
|
||||
* \note Index 0 is reserved for address 0 and shall never be used.
|
||||
*/
|
||||
uint32_t FindChildIndex(UsbDeviceAddress addr, uint32_t start = 1)
|
||||
{
|
||||
for (uint32_t i = (start < 1 || start >= MAX_DEVICES_ALLOWED) ? 1 : start; i < MAX_DEVICES_ALLOWED; ++i)
|
||||
{
|
||||
if (((UsbDeviceAddress*)&thePool[i].address)->bmParent == addr.bmAddress)
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Free address entry specified by index parameter.
|
||||
*
|
||||
* \note Calling FreeAddressByIndex only frees the USB address for possible
|
||||
* further assignement. However, it does not free the actual USB resources
|
||||
* used by the device. This can be made by calling the release() method
|
||||
* from any UsbDevice class implementing USBDeviceConfig.
|
||||
*
|
||||
* \param index Index pointing to a UsbDevice instance in the address pool.
|
||||
*
|
||||
* \note Calling FreeAddressByIndex with a 0 index param has no effect.
|
||||
*/
|
||||
void FreeAddressByIndex(uint32_t index)
|
||||
{
|
||||
// Zero field is reserved and should not be affected
|
||||
if (index == 0)
|
||||
return;
|
||||
|
||||
// If a hub was switched off all port addresses should be freed
|
||||
if (((UsbDeviceAddress*)&thePool[index].address)->bmHub == 1)
|
||||
{
|
||||
for (uint32_t i = 1; (i = FindChildIndex(*((UsbDeviceAddress*)&thePool[index].address), i) > 0); )
|
||||
FreeAddressByIndex(i);
|
||||
|
||||
// If the hub had the last allocated address, hubCounter should be decremented
|
||||
if (hubCounter == ((UsbDeviceAddress*)&thePool[index].address)->bmAddress)
|
||||
hubCounter --;
|
||||
}
|
||||
|
||||
InitEntry(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize all address poll entries at once.
|
||||
*/
|
||||
void InitAllAddresses()
|
||||
{
|
||||
for (uint32_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
|
||||
InitEntry(i);
|
||||
|
||||
hubCounter = 0;
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief AddressPoolImpl class constructor.
|
||||
*/
|
||||
AddressPoolImpl() : hubCounter(0)
|
||||
{
|
||||
// Init address zero (reserved)
|
||||
InitEntry(0);
|
||||
|
||||
// Init all remaing addresses
|
||||
InitAllAddresses();
|
||||
|
||||
// Configure ep0 used for enumeration
|
||||
dev0ep.deviceEpNum = 0;
|
||||
dev0ep.hostPipeNum = 0;
|
||||
dev0ep.maxPktSize = 8;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get a UsbDevice pointer from a USB device address.
|
||||
*
|
||||
* \param addr USB device address.
|
||||
*
|
||||
* \return UsbDevice pointer on success, 0 otherwise.
|
||||
*/
|
||||
virtual UsbDevice* GetUsbDevicePtr(uint32_t addr)
|
||||
{
|
||||
if (!addr)
|
||||
return thePool;
|
||||
|
||||
uint32_t index = FindAddressIndex(addr);
|
||||
|
||||
return (!index) ? 0 : (thePool + index);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Perform an operation specified by pfunc for each addressed
|
||||
* USB device.
|
||||
*
|
||||
* \param pfunc Any function pointer with type UsbDeviceHandleFunc.
|
||||
*/
|
||||
void ForEachUsbDevice(UsbDeviceHandleFunc pfunc)
|
||||
{
|
||||
if (!pfunc)
|
||||
return;
|
||||
|
||||
for (uint32_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
|
||||
if (thePool[i].address)
|
||||
pfunc(thePool + i);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Allocate a new USB device address.
|
||||
*
|
||||
* \note See UsbDeviceAddress definition for better understanding.
|
||||
*
|
||||
* \param parent USB device address of the Parent device.
|
||||
* \param is_hub Set to true if the corresponding device is a Hub, false
|
||||
* otherwise.
|
||||
* \param port USB device base address.
|
||||
*
|
||||
* \return UsbDevice pointer on success, 0 otherwise.
|
||||
*/
|
||||
virtual uint32_t AllocAddress(uint32_t parent, uint32_t is_hub = 0, uint32_t port = 0)
|
||||
{
|
||||
if (parent > 127 || port > 7)
|
||||
return 0;
|
||||
|
||||
if (is_hub && hubCounter == 7)
|
||||
return 0;
|
||||
|
||||
// Finds first empty address entry starting from one
|
||||
uint32_t index = FindAddressIndex(0);
|
||||
|
||||
// If empty entry is not found
|
||||
if (!index)
|
||||
return 0;
|
||||
|
||||
if (parent == 0)
|
||||
{
|
||||
if (is_hub)
|
||||
{
|
||||
thePool[index].address = 0x41;
|
||||
hubCounter++;
|
||||
}
|
||||
else
|
||||
thePool[index].address = 1;
|
||||
|
||||
return thePool[index].address;
|
||||
}
|
||||
|
||||
UsbDeviceAddress addr;
|
||||
|
||||
addr.bmParent = ((UsbDeviceAddress*)&parent)->bmAddress;
|
||||
|
||||
if (is_hub)
|
||||
{
|
||||
addr.bmHub = 1;
|
||||
addr.bmAddress = hubCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr.bmHub = 0;
|
||||
addr.bmAddress = port;
|
||||
}
|
||||
|
||||
thePool[index].address = *((uint8_t*)&addr);
|
||||
|
||||
return thePool[index].address;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Free the specified USB device address.
|
||||
*
|
||||
* \param addr USB device address to free.
|
||||
*/
|
||||
virtual void FreeAddress(uint32_t addr)
|
||||
{
|
||||
// If the root hub is disconnected all the addresses should be initialized
|
||||
if (addr == 0x41)
|
||||
{
|
||||
InitAllAddresses();
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t index = FindAddressIndex(addr);
|
||||
FreeAddressByIndex(index);
|
||||
};
|
||||
|
||||
// Returns number of hubs attached
|
||||
// It can be rather helpfull to find out if there are hubs attached than getting the exact number of hubs.
|
||||
/*uint32_t GetNumHubs()
|
||||
{
|
||||
return hubCounter;
|
||||
};
|
||||
|
||||
uint32_t GetNumDevices()
|
||||
{
|
||||
uint32_t counter = 0;
|
||||
|
||||
for (uint32_t i = 1; i < MAX_DEVICES_ALLOWED; ++i)
|
||||
if (thePool[i].address != 0);
|
||||
counter++;
|
||||
|
||||
return counter;
|
||||
};*/
|
||||
|
||||
};
|
||||
|
||||
#endif /* ADDRESS_H_INCLUDED */
|
405
libraries/USBHost/src/adk.cpp
Normal file
405
libraries/USBHost/src/adk.cpp
Normal file
@ -0,0 +1,405 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
/* Google ADK interface */
|
||||
|
||||
#include "adk.h"
|
||||
|
||||
const uint32_t ADK::epDataInIndex = 1;
|
||||
const uint32_t ADK::epDataOutIndex = 2;
|
||||
|
||||
/**
|
||||
* \brief ADK class constructor.
|
||||
*/
|
||||
ADK::ADK(USBHost *p, const char* pmanufacturer,
|
||||
const char* pmodel,
|
||||
const char* pdescription,
|
||||
const char* pversion,
|
||||
const char* puri,
|
||||
const char* pserial) :
|
||||
manufacturer(pmanufacturer),
|
||||
model(pmodel),
|
||||
description(pdescription),
|
||||
version(pversion),
|
||||
uri(puri),
|
||||
serial(pserial),
|
||||
pUsb(p),
|
||||
bAddress(0),
|
||||
bNumEP(1),
|
||||
ready(false)
|
||||
{
|
||||
// Initialize endpoint data structures
|
||||
for (uint32_t i = 0; i < ADK_MAX_ENDPOINTS; ++i)
|
||||
{
|
||||
epInfo[i].deviceEpNum = 0;
|
||||
epInfo[i].hostPipeNum = 0;
|
||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||
epInfo[i].epAttribs = 0;
|
||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
||||
}
|
||||
|
||||
// Register in USB subsystem
|
||||
if (pUsb)
|
||||
{
|
||||
pUsb->RegisterDeviceClass(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize connection to an Android Phone.
|
||||
*
|
||||
* \param parent USB device address of the Parent device.
|
||||
* \param port USB device base address.
|
||||
* \param lowspeed USB device speed.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t ADK::Init(uint32_t parent, uint32_t port, uint32_t lowspeed)
|
||||
{
|
||||
|
||||
uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
|
||||
uint32_t rcode = 0;
|
||||
UsbDevice *p = NULL;
|
||||
EpInfo *oldep_ptr = NULL;
|
||||
uint32_t adkproto = -1;
|
||||
uint32_t num_of_conf = 0;
|
||||
|
||||
// Get memory address of USB device address pool
|
||||
AddressPool &addrPool = pUsb->GetAddressPool();
|
||||
|
||||
TRACE_USBHOST(printf("ADK::Init\r\n");)
|
||||
|
||||
// Check if address has already been assigned to an instance
|
||||
if (bAddress)
|
||||
{
|
||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||
}
|
||||
|
||||
// Get pointer to pseudo device with address 0 assigned
|
||||
p = addrPool.GetUsbDevicePtr(0);
|
||||
|
||||
if (!p)
|
||||
{
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
}
|
||||
|
||||
if (!p->epinfo)
|
||||
{
|
||||
return USB_ERROR_EPINFO_IS_NULL;
|
||||
}
|
||||
|
||||
// Save old pointer to EP_RECORD of address 0
|
||||
oldep_ptr = p->epinfo;
|
||||
|
||||
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
||||
p->epinfo = epInfo;
|
||||
|
||||
p->lowspeed = lowspeed;
|
||||
|
||||
// Get device descriptor
|
||||
rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);
|
||||
|
||||
// Restore p->epinfo
|
||||
p->epinfo = oldep_ptr;
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
goto FailGetDevDescr;
|
||||
}
|
||||
|
||||
// Allocate new address according to device class
|
||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||
|
||||
// Extract Max Packet Size from device descriptor
|
||||
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
||||
|
||||
// Assign new address to the device
|
||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||
if (rcode)
|
||||
{
|
||||
p->lowspeed = false;
|
||||
addrPool.FreeAddress(bAddress);
|
||||
bAddress = 0;
|
||||
TRACE_USBHOST(printf("ADK::Init : setAddr failed with rcode %lu\r\n", rcode);)
|
||||
return rcode;
|
||||
}
|
||||
|
||||
TRACE_USBHOST(printf("ADK::Init : device address is now %lu\r\n", bAddress);)
|
||||
|
||||
p->lowspeed = false;
|
||||
|
||||
//get pointer to assigned address record
|
||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||
if (!p)
|
||||
{
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
}
|
||||
|
||||
p->lowspeed = lowspeed;
|
||||
|
||||
// Assign epInfo to epinfo pointer - only EP0 is known
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||
if (rcode)
|
||||
{
|
||||
goto FailSetDevTblEntry;
|
||||
}
|
||||
|
||||
// Check if ADK device is already in accessory mode; if yes, configure and exit
|
||||
if (((USB_DEVICE_DESCRIPTOR*)buf)->idVendor == ADK_VID &&
|
||||
(((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADK_PID || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADB_PID))
|
||||
{
|
||||
TRACE_USBHOST(printf("ADK::Init : Accessory mode device detected\r\n");)
|
||||
|
||||
/* Go through configurations, find first bulk-IN, bulk-OUT EP, fill epInfo and quit */
|
||||
num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
|
||||
|
||||
TRACE_USBHOST(printf("ADK::Init : number of configuration is %lu\r\n", num_of_conf);)
|
||||
|
||||
for (uint32_t i = 0; i < num_of_conf; ++i)
|
||||
{
|
||||
ConfigDescParser<0, 0, 0, 0> confDescrParser(this);
|
||||
|
||||
delay(1);
|
||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||
|
||||
#if defined(XOOM)
|
||||
//Added by Jaylen Scott Vanorden
|
||||
if (rcode)
|
||||
{
|
||||
TRACE_USBHOST(printf("ADK::Init : Got 1st bad code for config: %lu\r\n", rcode);)
|
||||
|
||||
// Try once more
|
||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
goto FailGetConfDescr;
|
||||
}
|
||||
|
||||
if (bNumEP > 2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bNumEP == 3)
|
||||
{
|
||||
// Assign epInfo to epinfo pointer - this time all 3 endpoins
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
|
||||
if (rcode)
|
||||
{
|
||||
goto FailSetDevTblEntry;
|
||||
}
|
||||
}
|
||||
|
||||
// Set Configuration Value
|
||||
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
||||
if (rcode)
|
||||
{
|
||||
goto FailSetConf;
|
||||
}
|
||||
|
||||
TRACE_USBHOST(printf("ADK::Init : ADK device configured successfully\r\n");)
|
||||
ready = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Probe device - get accessory protocol revision
|
||||
delay(1);
|
||||
rcode = getProto((uint8_t*)&adkproto);
|
||||
|
||||
#if defined(XOOM)
|
||||
// Added by Jaylen Scott Vanorden
|
||||
if (rcode)
|
||||
{
|
||||
TRACE_USBHOST(printf("ADK::Init : Got 1st bad code for config: %lu\r\n", rcode);)
|
||||
|
||||
// Try once more
|
||||
rcode = getProto((uint8_t*)&adkproto );
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
goto FailGetProto;
|
||||
}
|
||||
TRACE_USBHOST(printf("ADK::Init : DK protocol rev. %lu", adkproto);)
|
||||
|
||||
// Send ID strings
|
||||
sendStr(ACCESSORY_STRING_MANUFACTURER, manufacturer);
|
||||
sendStr(ACCESSORY_STRING_MODEL, model);
|
||||
sendStr(ACCESSORY_STRING_DESCRIPTION, description);
|
||||
sendStr(ACCESSORY_STRING_VERSION, version);
|
||||
sendStr(ACCESSORY_STRING_URI, uri);
|
||||
sendStr(ACCESSORY_STRING_SERIAL, serial);
|
||||
|
||||
// Switch to accessory mode
|
||||
// The Android phone will reset
|
||||
rcode = switchAcc();
|
||||
if (rcode)
|
||||
{
|
||||
goto FailSwAcc;
|
||||
}
|
||||
rcode = -1;
|
||||
goto SwAttempt; // Switch to accessory mode
|
||||
|
||||
// Diagnostic messages
|
||||
FailGetDevDescr:
|
||||
TRACE_USBHOST(printf("ADK::Init getDevDescr : ");)
|
||||
goto Fail;
|
||||
|
||||
FailSetDevTblEntry:
|
||||
TRACE_USBHOST(printf("ADK::Init setDevTblEn : ");)
|
||||
goto Fail;
|
||||
|
||||
FailGetProto:
|
||||
TRACE_USBHOST(printf("ADK::Init getProto : ");)
|
||||
goto Fail;
|
||||
|
||||
FailSwAcc:
|
||||
TRACE_USBHOST(printf("ADK::Init swAcc : ");)
|
||||
goto Fail;
|
||||
|
||||
SwAttempt:
|
||||
TRACE_USBHOST(printf("ADK::Init Accessory mode switch attempt : ");)
|
||||
goto Fail;
|
||||
|
||||
FailGetConfDescr:
|
||||
TRACE_USBHOST(printf("ADK::Init getConf : ");)
|
||||
goto Fail;
|
||||
|
||||
FailSetConf:
|
||||
TRACE_USBHOST(printf("ADK::Init setConf : ");)
|
||||
goto Fail;
|
||||
|
||||
Fail:
|
||||
TRACE_USBHOST(printf("error code: %lu\r\n", rcode);)
|
||||
Release();
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Extract bulk-IN and bulk-OUT endpoint information from configuration
|
||||
* descriptor.
|
||||
*
|
||||
* \param conf Configuration number.
|
||||
* \param iface Interface number.
|
||||
* \param alt Alternate setting.
|
||||
* \param proto Protocol version used.
|
||||
* \param pep Pointer to endpoint descriptor.
|
||||
*/
|
||||
void ADK::EndpointXtract(uint32_t conf, uint32_t iface, uint32_t alt, uint32_t proto, const USB_ENDPOINT_DESCRIPTOR *pep)
|
||||
{
|
||||
if (bNumEP == 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bConfNum = conf;
|
||||
|
||||
uint32_t index = 0;
|
||||
uint32_t pipe = 0;
|
||||
|
||||
if ((pep->bmAttributes & 0x02) == 2)
|
||||
{
|
||||
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
|
||||
}
|
||||
|
||||
// Fill in the endpoint info structure
|
||||
epInfo[index].deviceEpNum = pep->bEndpointAddress & 0x0F;
|
||||
epInfo[index].maxPktSize = pep->wMaxPacketSize;
|
||||
|
||||
TRACE_USBHOST(printf("ADK::EndpointXtract : Found new endpoint\r\n");)
|
||||
TRACE_USBHOST(printf("ADK::EndpointXtract : deviceEpNum: %lu\r\n", epInfo[index].deviceEpNum);)
|
||||
TRACE_USBHOST(printf("ADK::EndpointXtract : maxPktSize: %lu\r\n", epInfo[index].maxPktSize);)
|
||||
TRACE_USBHOST(printf("ADK::EndpointXtract : index: %lu\r\n", index);)
|
||||
|
||||
if (index == epDataInIndex)
|
||||
pipe = UHD_Pipe_Alloc(bAddress, epInfo[index].deviceEpNum, UOTGHS_HSTPIPCFG_PTYPE_BLK, UOTGHS_HSTPIPCFG_PTOKEN_IN, epInfo[index].maxPktSize, 0, UOTGHS_HSTPIPCFG_PBK_1_BANK);
|
||||
else if (index == epDataOutIndex)
|
||||
pipe = UHD_Pipe_Alloc(bAddress, epInfo[index].deviceEpNum, UOTGHS_HSTPIPCFG_PTYPE_BLK, UOTGHS_HSTPIPCFG_PTOKEN_OUT, epInfo[index].maxPktSize, 0, UOTGHS_HSTPIPCFG_PBK_1_BANK);
|
||||
|
||||
// Ensure pipe allocation is okay
|
||||
if (pipe == 0)
|
||||
{
|
||||
TRACE_USBHOST(printf("ADK::EndpointXtract : Pipe allocation failure\r\n");)
|
||||
// Enumeration failed, so user should not perform write/read since isConnected will return false
|
||||
return;
|
||||
}
|
||||
|
||||
epInfo[index].hostPipeNum = pipe;
|
||||
|
||||
bNumEP++;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Release USB allocated resources (pipes and address).
|
||||
*
|
||||
* \note Release call is made from USBHost.task() on disconnection events.
|
||||
* \note Release call is made from Init() on enumeration failure.
|
||||
*
|
||||
* \return Always 0.
|
||||
*/
|
||||
uint32_t ADK::Release()
|
||||
{
|
||||
// Free allocated host pipes
|
||||
UHD_Pipe_Free(epInfo[epDataInIndex].hostPipeNum);
|
||||
UHD_Pipe_Free(epInfo[epDataOutIndex].hostPipeNum);
|
||||
|
||||
// Free allocated USB address
|
||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||
|
||||
// Must have to be reset to 1
|
||||
bNumEP = 1;
|
||||
|
||||
bAddress = 0;
|
||||
ready = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read from ADK.
|
||||
*
|
||||
* \param nreadbytes Return value containing the number of read bytes.
|
||||
* \param datalen Buffer length.
|
||||
* \param dataptr Buffer to store the incoming data.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t ADK::read(uint32_t *nreadbytes, uint32_t datalen, uint8_t *dataptr)
|
||||
{
|
||||
*nreadbytes = datalen;
|
||||
return pUsb->inTransfer(bAddress, epInfo[epDataInIndex].deviceEpNum, nreadbytes, dataptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write to ADK.
|
||||
*
|
||||
* \param datalen Amount of data to send. This parameter shall not exceed
|
||||
* dataptr length.
|
||||
* \param dataptr Buffer containing the data to be sent.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t ADK::write(uint32_t datalen, uint8_t *dataptr)
|
||||
{
|
||||
return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].deviceEpNum, datalen, dataptr);
|
||||
}
|
150
libraries/USBHost/src/adk.h
Normal file
150
libraries/USBHost/src/adk.h
Normal file
@ -0,0 +1,150 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
/* Google ADK interface support header */
|
||||
|
||||
#ifndef ADK_H_INCLUDED
|
||||
#define ADK_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
#include "usb_ch9.h"
|
||||
#include "Usb.h"
|
||||
#include "hid.h"
|
||||
#include "Arduino.h"
|
||||
#include "confdescparser.h"
|
||||
|
||||
#define ADK_VID 0x18D1
|
||||
#define ADK_PID 0x2D00
|
||||
#define ADB_PID 0x2D01
|
||||
|
||||
#define XOOM //enables repeating getProto() and getConf() attempts
|
||||
//necessary for slow devices such as Motorola XOOM
|
||||
//defined by default, can be commented out to save memory
|
||||
|
||||
/* Requests */
|
||||
|
||||
#define ADK_GETPROTO 51 //check USB accessory protocol version
|
||||
#define ADK_SENDSTR 52 //send identifying string
|
||||
#define ADK_ACCSTART 53 //start device in accessory mode
|
||||
|
||||
#define bmREQ_ADK_GET USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_VENDOR|USB_SETUP_RECIPIENT_DEVICE
|
||||
#define bmREQ_ADK_SEND USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_VENDOR|USB_SETUP_RECIPIENT_DEVICE
|
||||
|
||||
#define ACCESSORY_STRING_MANUFACTURER 0
|
||||
#define ACCESSORY_STRING_MODEL 1
|
||||
#define ACCESSORY_STRING_DESCRIPTION 2
|
||||
#define ACCESSORY_STRING_VERSION 3
|
||||
#define ACCESSORY_STRING_URI 4
|
||||
#define ACCESSORY_STRING_SERIAL 5
|
||||
|
||||
#define ADK_MAX_ENDPOINTS 3 //endpoint 0, bulk_IN, bulk_OUT
|
||||
|
||||
/**
|
||||
* \class ADK definition.
|
||||
*/
|
||||
class ADK : public USBDeviceConfig, public UsbConfigXtracter
|
||||
{
|
||||
private:
|
||||
/* ID strings */
|
||||
const char* manufacturer;
|
||||
const char* model;
|
||||
const char* description;
|
||||
const char* version;
|
||||
const char* uri;
|
||||
const char* serial;
|
||||
|
||||
/* ADK proprietary requests */
|
||||
uint32_t getProto(uint8_t* adkproto);
|
||||
uint32_t sendStr(uint32_t index, const char* str);
|
||||
uint32_t switchAcc(void);
|
||||
|
||||
protected:
|
||||
static const uint32_t epDataInIndex; // DataIn endpoint index
|
||||
static const uint32_t epDataOutIndex; // DataOUT endpoint index
|
||||
|
||||
/* Mandatory members */
|
||||
USBHost *pUsb;
|
||||
uint32_t bAddress; // Device USB address
|
||||
uint32_t bConfNum; // configuration number
|
||||
|
||||
uint32_t bNumEP; // total number of EP in the configuration
|
||||
bool ready;
|
||||
|
||||
/* Endpoint data structure describing the device EP */
|
||||
EpInfo epInfo[ADK_MAX_ENDPOINTS];
|
||||
|
||||
public:
|
||||
ADK(USBHost *pUsb, const char* pmanufacturer,
|
||||
const char* pmodel,
|
||||
const char* pdescription,
|
||||
const char* pversion,
|
||||
const char* puri,
|
||||
const char* pserial);
|
||||
|
||||
// Methods for receiving and sending data
|
||||
uint32_t read(uint32_t *nreadbytes, uint32_t datalen, uint8_t *dataptr);
|
||||
uint32_t write(uint32_t datalen, uint8_t *dataptr);
|
||||
|
||||
|
||||
// USBDeviceConfig implementation
|
||||
virtual uint32_t Init(uint32_t parent, uint32_t port, uint32_t lowspeed);
|
||||
virtual uint32_t Release();
|
||||
virtual uint32_t Poll() { return 0; }; // not implemented
|
||||
virtual uint32_t GetAddress() { return bAddress; };
|
||||
virtual bool isReady() { return ready; };
|
||||
|
||||
// UsbConfigXtracter implementation
|
||||
virtual void EndpointXtract(uint32_t conf, uint32_t iface, uint32_t alt, uint32_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get ADK protocol version.
|
||||
*
|
||||
* \param adkproto Empty buffer to be filled by getProto (2 bytes) with the ADK
|
||||
* protocol version value.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
inline uint32_t ADK::getProto(uint8_t* adkproto)
|
||||
{
|
||||
return (pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_GET, ADK_GETPROTO, 0, 0, 0, 2, 2, adkproto, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Send ADK string.
|
||||
*
|
||||
* \param index String index.
|
||||
* \param str String to send.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
inline uint32_t ADK::sendStr(uint32_t index, const char* str)
|
||||
{
|
||||
return (pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_SENDSTR, 0, 0, index, strlen(str) + 1, strlen(str) + 1, (uint8_t*)str, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Send a switch to accessory mode request.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
inline uint32_t ADK::switchAcc(void)
|
||||
{
|
||||
return (pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_ACCSTART, 0, 0, 0, 0, 0, NULL, NULL));
|
||||
}
|
||||
|
||||
#endif /* ADK_H_INCLUDED */
|
241
libraries/USBHost/src/confdescparser.h
Normal file
241
libraries/USBHost/src/confdescparser.h
Normal file
@ -0,0 +1,241 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
#ifndef CONFDESCPARSER_H_INCLUDED
|
||||
#define CONFDESCPARSER_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
#include "parsetools.h"
|
||||
|
||||
/**
|
||||
* \class Abstract UsbConfigXtracter definition.
|
||||
*
|
||||
* \note This class is used for extracting USB endpoint descriptors.
|
||||
*/
|
||||
class UsbConfigXtracter
|
||||
{
|
||||
public:
|
||||
virtual void EndpointXtract(uint32_t conf, uint32_t iface, uint32_t alt, uint32_t proto, const USB_ENDPOINT_DESCRIPTOR *ep) = 0;
|
||||
};
|
||||
|
||||
#define CP_MASK_COMPARE_CLASS 1
|
||||
#define CP_MASK_COMPARE_SUBCLASS 2
|
||||
#define CP_MASK_COMPARE_PROTOCOL 4
|
||||
#define CP_MASK_COMPARE_ALL 7
|
||||
|
||||
/**
|
||||
* \class ConfigDescParser definition.
|
||||
*
|
||||
* \note This class is used for parsing configuration descriptors.
|
||||
*/
|
||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
||||
class ConfigDescParser : public USBReadParser
|
||||
{
|
||||
UsbConfigXtracter *theXtractor;
|
||||
MultiValueBuffer theBuffer;
|
||||
MultiByteValueParser valParser;
|
||||
ByteSkipper theSkipper;
|
||||
uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/];
|
||||
|
||||
uint32_t stateParseDescr; // ParseDescriptor state
|
||||
|
||||
uint32_t dscrLen; // Descriptor length
|
||||
uint32_t dscrType; // Descriptor type
|
||||
|
||||
bool isGoodInterface; // Apropriate interface flag
|
||||
uint32_t confValue; // Configuration value
|
||||
uint32_t protoValue; // Protocol value
|
||||
uint32_t ifaceNumber; // Interface number
|
||||
uint32_t ifaceAltSet; // Interface alternate settings
|
||||
|
||||
bool ParseDescriptor(uint8_t **pp, uint32_t *pcntdn);
|
||||
|
||||
void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
|
||||
|
||||
public:
|
||||
ConfigDescParser(UsbConfigXtracter *xtractor);
|
||||
virtual void Parse(const uint32_t len, const uint8_t *pbuf, const uint32_t &offset);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief ConfigDescParser class constructor.
|
||||
*
|
||||
* \param xtractor Is saved as ConfigDescParser attribute and later used as a
|
||||
* callback for parsing the endpoint descriptors.
|
||||
*
|
||||
* \note During enumeration stage, all supported USB classes invoke
|
||||
* ConfigDescParser with "this" as parameter, meaning that one class is also
|
||||
* responsible for parsing its endpoint descriptors. This makes sense since
|
||||
* each USB class handles different number of endpoints and configurations.
|
||||
* For instance see ADK::Init from ADK class.
|
||||
*/
|
||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
||||
ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ConfigDescParser(UsbConfigXtracter *xtractor) :
|
||||
theXtractor(xtractor),
|
||||
stateParseDescr(0),
|
||||
dscrLen(0),
|
||||
dscrType(0)
|
||||
{
|
||||
theBuffer.pValue = varBuffer;
|
||||
valParser.Initialize(&theBuffer);
|
||||
theSkipper.Initialize(&theBuffer);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Parse a complete USB configuration descriptor.
|
||||
*
|
||||
* \param len Buffer length.
|
||||
* \param pbuf Buffer containing the configuration descriptor.
|
||||
* \param offset Current offset position.
|
||||
*/
|
||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
||||
void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uint32_t len, const uint8_t *pbuf, const uint32_t &offset)
|
||||
{
|
||||
uint32_t cntdn = len;
|
||||
uint8_t *p = (uint8_t*)pbuf;
|
||||
|
||||
while (cntdn)
|
||||
if (!ParseDescriptor(&p, &cntdn))
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Parse a USB configuration descriptor.
|
||||
* Takes values for class, subclass, protocol fields in interface descriptor
|
||||
* and compare masks for them. When the match is found, calls EndpointXtract
|
||||
* passing buffer containing endpoint descriptor.
|
||||
*
|
||||
* \note This method should not be called directly, use Parse() instead.
|
||||
*
|
||||
* \param pcntdn Buffer length.
|
||||
* \param pp Buffer containing the configuration descriptor.
|
||||
*
|
||||
* \return true if data remains in the buffer for parsing, false otherwise.
|
||||
*/
|
||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
||||
bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor(uint8_t **pp, uint32_t *pcntdn)
|
||||
{
|
||||
switch (stateParseDescr)
|
||||
{
|
||||
case 0:
|
||||
theBuffer.valueSize = 2;
|
||||
valParser.Initialize(&theBuffer);
|
||||
stateParseDescr = 1;
|
||||
case 1:
|
||||
if (!valParser.Parse(pp, pcntdn))
|
||||
return false;
|
||||
dscrLen = *((uint8_t*)theBuffer.pValue);
|
||||
dscrType = *((uint8_t*)theBuffer.pValue + 1);
|
||||
stateParseDescr = 2;
|
||||
case 2:
|
||||
// This is a sort of hack. Assuming that two bytes are already in the buffer
|
||||
// the pointer is positioned two bytes ahead in order for the rest of descriptor
|
||||
// to be read right after the size and the type fields.
|
||||
// This should be used carefuly. varBuffer should be used directly to handle data
|
||||
// in the buffer.
|
||||
theBuffer.pValue = varBuffer + 2;
|
||||
stateParseDescr = 3;
|
||||
case 3:
|
||||
switch (dscrType)
|
||||
{
|
||||
case USB_DESCRIPTOR_INTERFACE:
|
||||
isGoodInterface = false;
|
||||
case USB_DESCRIPTOR_CONFIGURATION:
|
||||
theBuffer.valueSize = sizeof(USB_CONFIGURATION_DESCRIPTOR) - 2;
|
||||
break;
|
||||
case USB_DESCRIPTOR_ENDPOINT:
|
||||
theBuffer.valueSize = sizeof(USB_ENDPOINT_DESCRIPTOR) - 2;
|
||||
break;
|
||||
case HID_DESCRIPTOR_HID:
|
||||
theBuffer.valueSize = dscrLen - 2;
|
||||
break;
|
||||
}
|
||||
valParser.Initialize(&theBuffer);
|
||||
stateParseDescr = 4;
|
||||
case 4:
|
||||
switch (dscrType)
|
||||
{
|
||||
case USB_DESCRIPTOR_CONFIGURATION:
|
||||
if (!valParser.Parse(pp, pcntdn))
|
||||
return false;
|
||||
confValue = ((USB_CONFIGURATION_DESCRIPTOR*)varBuffer)->bConfigurationValue;
|
||||
break;
|
||||
case USB_DESCRIPTOR_INTERFACE:
|
||||
if (!valParser.Parse(pp, pcntdn))
|
||||
return false;
|
||||
if ((MASK & CP_MASK_COMPARE_CLASS) && ((USB_INTERFACE_DESCRIPTOR*)varBuffer)->bInterfaceClass != CLASS_ID)
|
||||
break;
|
||||
if ((MASK & CP_MASK_COMPARE_SUBCLASS) && ((USB_INTERFACE_DESCRIPTOR*)varBuffer)->bInterfaceSubClass != SUBCLASS_ID)
|
||||
break;
|
||||
if ((MASK & CP_MASK_COMPARE_PROTOCOL) && ((USB_INTERFACE_DESCRIPTOR*)varBuffer)->bInterfaceProtocol != PROTOCOL_ID)
|
||||
break;
|
||||
|
||||
isGoodInterface = true;
|
||||
ifaceNumber = ((USB_INTERFACE_DESCRIPTOR*)varBuffer)->bInterfaceNumber;
|
||||
ifaceAltSet = ((USB_INTERFACE_DESCRIPTOR*)varBuffer)->bAlternateSetting;
|
||||
protoValue = ((USB_INTERFACE_DESCRIPTOR*)varBuffer)->bInterfaceProtocol;
|
||||
break;
|
||||
case USB_DESCRIPTOR_ENDPOINT:
|
||||
if (!valParser.Parse(pp, pcntdn))
|
||||
return false;
|
||||
if (isGoodInterface)
|
||||
if (theXtractor)
|
||||
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
|
||||
break;
|
||||
//case HID_DESCRIPTOR_HID:
|
||||
// if (!valParser.Parse(pp, pcntdn))
|
||||
// return false;
|
||||
// PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
|
||||
// break;
|
||||
default:
|
||||
if (!theSkipper.Skip(pp, pcntdn, dscrLen - 2))
|
||||
return false;
|
||||
}
|
||||
theBuffer.pValue = varBuffer;
|
||||
stateParseDescr = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Print HID descriptor.
|
||||
*
|
||||
* \note TRACE_USBHOST macro must be enabled. See Usb.h for reference.
|
||||
*
|
||||
* \param pDesc Pointer to HID descriptor.
|
||||
*/
|
||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
||||
void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc)
|
||||
{
|
||||
TRACE_USBHOST(printf("ConfigDescParser::PrintHidDescriptor : bDescLength: %d\r\n", pDesc->bLength);)
|
||||
TRACE_USBHOST(printf("ConfigDescParser::PrintHidDescriptor : bDescriptorType: %d\r\n", pDesc->bDescriptorType);)
|
||||
TRACE_USBHOST(printf("ConfigDescParser::PrintHidDescriptor : bcdHID: %d\r\n", pDesc->bcdHID);)
|
||||
TRACE_USBHOST(printf("ConfigDescParser::PrintHidDescriptor : bCountryCode: %d\r\n", pDesc->bCountryCode);)
|
||||
TRACE_USBHOST(printf("ConfigDescParser::PrintHidDescriptor : bNumDescriptors: %d\r\n", pDesc->bNumDescriptors);)
|
||||
TRACE_USBHOST(printf("ConfigDescParser::PrintHidDescriptor : bDescrType: %d\r\n", pDesc->bDescrType);)
|
||||
TRACE_USBHOST(printf("ConfigDescParser::PrintHidDescriptor : wDescriptorLength: %d\r\n", pDesc->wDescriptorLength);)
|
||||
|
||||
for (uint32_t i = 0; i < pDesc->bNumDescriptors; ++i)
|
||||
{
|
||||
HID_CLASS_DESCRIPTOR_LEN_AND_TYPE *pLT = (HID_CLASS_DESCRIPTOR_LEN_AND_TYPE*)&(pDesc->bDescrType);
|
||||
|
||||
TRACE_USBHOST(printf("ConfigDescParser::PrintHidDescriptor : bDescrType: %d\r\n", pLT[i].bDescrType);)
|
||||
TRACE_USBHOST(printf("ConfigDescParser::PrintHidDescriptor : wDescriptorLength: %d\r\n", pLT[i].wDescriptorLength);)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFDESCPARSER_H_INCLUDED */
|
202
libraries/USBHost/src/hid.h
Normal file
202
libraries/USBHost/src/hid.h
Normal file
@ -0,0 +1,202 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
#ifndef HID_H_INCLUDED
|
||||
#define HID_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
#include "usb_ch9.h"
|
||||
#include "Usb.h"
|
||||
#include "Arduino.h"
|
||||
#include "confdescparser.h"
|
||||
#include "hidusagestr.h"
|
||||
|
||||
#define DATA_SIZE_MASK 0x03
|
||||
#define TYPE_MASK 0x0C
|
||||
#define TAG_MASK 0xF0
|
||||
|
||||
#define DATA_SIZE_0 0x00
|
||||
#define DATA_SIZE_1 0x01
|
||||
#define DATA_SIZE_2 0x02
|
||||
#define DATA_SIZE_4 0x03
|
||||
|
||||
#define TYPE_MAIN 0x00
|
||||
#define TYPE_GLOBAL 0x04
|
||||
#define TYPE_LOCAL 0x08
|
||||
|
||||
#define TAG_MAIN_INPUT 0x80
|
||||
#define TAG_MAIN_OUTPUT 0x90
|
||||
#define TAG_MAIN_COLLECTION 0xA0
|
||||
#define TAG_MAIN_FEATURE 0xB0
|
||||
#define TAG_MAIN_ENDCOLLECTION 0xC0
|
||||
|
||||
#define TAG_GLOBAL_USAGEPAGE 0x00
|
||||
#define TAG_GLOBAL_LOGICALMIN 0x10
|
||||
#define TAG_GLOBAL_LOGICALMAX 0x20
|
||||
#define TAG_GLOBAL_PHYSMIN 0x30
|
||||
#define TAG_GLOBAL_PHYSMAX 0x40
|
||||
#define TAG_GLOBAL_UNITEXP 0x50
|
||||
#define TAG_GLOBAL_UNIT 0x60
|
||||
#define TAG_GLOBAL_REPORTSIZE 0x70
|
||||
#define TAG_GLOBAL_REPORTID 0x80
|
||||
#define TAG_GLOBAL_REPORTCOUNT 0x90
|
||||
#define TAG_GLOBAL_PUSH 0xA0
|
||||
#define TAG_GLOBAL_POP 0xB0
|
||||
|
||||
#define TAG_LOCAL_USAGE 0x00
|
||||
#define TAG_LOCAL_USAGEMIN 0x10
|
||||
#define TAG_LOCAL_USAGEMAX 0x20
|
||||
|
||||
/* HID requests */
|
||||
#define bmREQ_HIDOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||
#define bmREQ_HIDIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||
#define bmREQ_HIDREPORT USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_INTERFACE
|
||||
|
||||
/* HID constants. Not part of chapter 9 */
|
||||
/* Class-Specific Requests */
|
||||
#define HID_REQUEST_GET_REPORT 0x01
|
||||
#define HID_REQUEST_GET_IDLE 0x02
|
||||
#define HID_REQUEST_GET_PROTOCOL 0x03
|
||||
#define HID_REQUEST_SET_REPORT 0x09
|
||||
#define HID_REQUEST_SET_IDLE 0x0A
|
||||
#define HID_REQUEST_SET_PROTOCOL 0x0B
|
||||
|
||||
/* Class Descriptor Types */
|
||||
#define HID_DESCRIPTOR_HID 0x21
|
||||
#define HID_DESCRIPTOR_REPORT 0x22
|
||||
#define HID_DESRIPTOR_PHY 0x23
|
||||
|
||||
/* Protocol Selection */
|
||||
#define HID_BOOT_PROTOCOL 0x00
|
||||
#define HID_RPT_PROTOCOL 0x01
|
||||
|
||||
/* HID Interface Class Code */
|
||||
#define HID_INTF 0x03
|
||||
|
||||
/* HID Interface Class SubClass Codes */
|
||||
#define HID_BOOT_INTF_SUBCLASS 0x01
|
||||
|
||||
/* HID Interface Class Protocol Codes */
|
||||
#define HID_PROTOCOL_NONE 0x00
|
||||
#define HID_PROTOCOL_KEYBOARD 0x01
|
||||
#define HID_PROTOCOL_MOUSE 0x02
|
||||
|
||||
/**
|
||||
* \brief HidItemPrefix definition.
|
||||
*/
|
||||
struct HidItemPrefix // Not used
|
||||
{
|
||||
uint8_t bSize : 2;
|
||||
uint8_t bType : 2;
|
||||
uint8_t bTag : 4;
|
||||
};
|
||||
|
||||
#define HID_ITEM_TYPE_MAIN 0
|
||||
#define HID_ITEM_TYPE_GLOBAL 1
|
||||
#define HID_ITEM_TYPE_LOCAL 2
|
||||
#define HID_ITEM_TYPE_RESERVED 3
|
||||
|
||||
#define HID_LONG_ITEM_PREFIX 0xfe // Long item prefix value
|
||||
|
||||
#define bmHID_MAIN_ITEM_TAG 0xfc // Main item tag mask
|
||||
|
||||
#define bmHID_MAIN_ITEM_INPUT 0x80 // Main item Input tag value
|
||||
#define bmHID_MAIN_ITEM_OUTPUT 0x90 // Main item Output tag value
|
||||
#define bmHID_MAIN_ITEM_FEATURE 0xb0 // Main item Feature tag value
|
||||
#define bmHID_MAIN_ITEM_COLLECTION 0xa0 // Main item Collection tag value
|
||||
#define bmHID_MAIN_ITEM_END_COLLECTION 0xce // Main item End Collection tag value
|
||||
|
||||
#define HID_MAIN_ITEM_COLLECTION_PHYSICAL 0
|
||||
#define HID_MAIN_ITEM_COLLECTION_APPLICATION 1
|
||||
#define HID_MAIN_ITEM_COLLECTION_LOGICAL 2
|
||||
#define HID_MAIN_ITEM_COLLECTION_REPORT 3
|
||||
#define HID_MAIN_ITEM_COLLECTION_NAMED_ARRAY 4
|
||||
#define HID_MAIN_ITEM_COLLECTION_USAGE_SWITCH 5
|
||||
#define HID_MAIN_ITEM_COLLECTION_USAGE_MODIFIER 6
|
||||
|
||||
/**
|
||||
* \brief MainItemIOFeature definition.
|
||||
*/
|
||||
struct MainItemIOFeature // Not used
|
||||
{
|
||||
uint8_t bmIsConstantOrData : 1;
|
||||
uint8_t bmIsArrayOrVariable : 1;
|
||||
uint8_t bmIsRelativeOrAbsolute : 1;
|
||||
uint8_t bmIsWrapOrNoWrap : 1;
|
||||
uint8_t bmIsNonLonearOrLinear : 1;
|
||||
uint8_t bmIsNoPreferedOrPrefered : 1;
|
||||
uint8_t bmIsNullOrNoNull : 1;
|
||||
uint8_t bmIsVolatileOrNonVolatile : 1;
|
||||
};
|
||||
|
||||
class HID;
|
||||
|
||||
/**
|
||||
* \class Abstract HIDReportParser definition.
|
||||
*
|
||||
* \note This class is used to implement HID report parsing.
|
||||
*/
|
||||
class HIDReportParser
|
||||
{
|
||||
public:
|
||||
virtual void Parse(HID *hid, bool is_rpt_id, uint32_t len, uint8_t *buf) = 0;
|
||||
};
|
||||
|
||||
#define MAX_REPORT_PARSERS 2
|
||||
#define HID_MAX_HID_CLASS_DESCRIPTORS 5
|
||||
|
||||
/**
|
||||
* \class HID definition.
|
||||
*/
|
||||
class HID : public USBDeviceConfig, public UsbConfigXtracter
|
||||
{
|
||||
protected:
|
||||
USBHost *pUsb; // USB class instance pointer
|
||||
uint32_t bAddress; // address
|
||||
|
||||
protected:
|
||||
static const uint32_t epInterruptInIndex = 1; // InterruptIN endpoint index
|
||||
static const uint32_t epInterruptOutIndex = 2; // InterruptOUT endpoint index
|
||||
|
||||
static const uint32_t maxHidInterfaces = 3;
|
||||
static const uint32_t maxEpPerInterface = 2;
|
||||
static const uint32_t totalEndpoints = (maxHidInterfaces * maxEpPerInterface + 1);
|
||||
|
||||
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
|
||||
void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
|
||||
|
||||
virtual HIDReportParser* GetReportParser(uint32_t id) { return 0; };
|
||||
|
||||
public:
|
||||
HID(USBHost *pusb) : pUsb(pusb) {};
|
||||
|
||||
const USBHost* GetUsb() { return pUsb; };
|
||||
virtual bool SetReportParser(uint32_t id, HIDReportParser *prs) { return false; };
|
||||
|
||||
uint32_t SetProtocol(uint32_t iface, uint32_t protocol);
|
||||
uint32_t GetProtocol(uint32_t iface, uint8_t* dataptr);
|
||||
uint32_t GetIdle(uint32_t iface, uint32_t reportID, uint8_t* dataptr);
|
||||
uint32_t SetIdle(uint32_t iface, uint32_t reportID, uint32_t duration);
|
||||
|
||||
uint32_t GetReportDescr(uint32_t ep, USBReadParser *parser = NULL);
|
||||
|
||||
uint32_t GetHidDescr(uint32_t ep, uint32_t nbytes, uint8_t* dataptr);
|
||||
uint32_t GetReport(uint32_t ep, uint32_t iface, uint32_t report_type, uint32_t report_id, uint32_t nbytes, uint8_t* dataptr);
|
||||
uint32_t SetReport(uint32_t ep, uint32_t iface, uint32_t report_type, uint32_t report_id, uint32_t nbytes, uint8_t* dataptr);
|
||||
};
|
||||
|
||||
#endif /* HID_H_INCLUDED */
|
141
libraries/USBHost/src/hid2.cpp
Normal file
141
libraries/USBHost/src/hid2.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
#include "hid.h"
|
||||
|
||||
/**
|
||||
* \brief Get HID report descriptor and parse it.
|
||||
*
|
||||
* \param ep USB device endpoint.
|
||||
* \param parser Parser used to decode report.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t HID::GetReportDescr(uint32_t ep, USBReadParser *parser)
|
||||
{
|
||||
const uint32_t constBufLen = 64;
|
||||
uint8_t buf[constBufLen];
|
||||
|
||||
return (pUsb->ctrlReq(bAddress, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00,
|
||||
HID_DESCRIPTOR_REPORT, 0x0000, 128, constBufLen, buf, (USBReadParser*)parser));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set HID report descriptor.
|
||||
*
|
||||
* \param ep USB device endpoint.
|
||||
* \param iface Interface number.
|
||||
* \param report_type HID report type.
|
||||
* \param report_id HID report ID.
|
||||
* \param nbytes Buffer length.
|
||||
* \param dataptr Buffer containing the HID report to send.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t HID::SetReport(uint32_t ep, uint32_t iface, uint32_t report_type, uint32_t report_id, uint32_t nbytes, uint8_t* dataptr)
|
||||
{
|
||||
return (pUsb->ctrlReq(bAddress, ep, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id, report_type, iface, nbytes, nbytes, dataptr, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get HID report descriptor.
|
||||
*
|
||||
* \param ep USB device endpoint.
|
||||
* \param iface Interface number.
|
||||
* \param report_type HID report type.
|
||||
* \param report_id HID report ID.
|
||||
* \param nbytes Buffer length.
|
||||
* \param dataptr Buffer containing the HID report to send.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t HID::GetReport(uint32_t ep, uint32_t iface, uint32_t report_type, uint32_t report_id, uint32_t nbytes, uint8_t* dataptr)
|
||||
{
|
||||
return (pUsb->ctrlReq(bAddress, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, iface, nbytes, nbytes, dataptr, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get HID idle status.
|
||||
*
|
||||
* \param iface Interface number.
|
||||
* \param report_id HID report ID.
|
||||
* \param dataptr Buffer to receive data. Size must be >= 1.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t HID::GetIdle(uint32_t iface, uint32_t report_id, uint8_t* dataptr)
|
||||
{
|
||||
return (pUsb->ctrlReq(bAddress, 0, bmREQ_HIDIN, HID_REQUEST_GET_IDLE, report_id, 0, iface, 0x0001, 0x0001, dataptr, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set HID idle status.
|
||||
*
|
||||
* \param iface Interface number.
|
||||
* \param report_id HID report ID.
|
||||
* \param duration Status duration.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t HID::SetIdle(uint32_t iface, uint32_t report_id, uint32_t duration)
|
||||
{
|
||||
return (pUsb->ctrlReq(bAddress, 0, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, report_id, duration, iface, 0x0000, 0x0000, NULL, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set HID protocol.
|
||||
*
|
||||
* \param iface Interface number.
|
||||
* \param protocol Protocol value.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t HID::SetProtocol(uint32_t iface, uint32_t protocol)
|
||||
{
|
||||
return (pUsb->ctrlReq(bAddress, 0, bmREQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, iface, 0x0000, 0x0000, NULL, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get HID protocol.
|
||||
*
|
||||
* \param iface Interface number.
|
||||
* \param dataptr Buffer used to store protocol value. Size must be >= 1.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint32_t HID::GetProtocol(uint32_t iface, uint8_t* dataptr)
|
||||
{
|
||||
return (pUsb->ctrlReq(bAddress, 0, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, iface, 0x0001, 0x0001, dataptr, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Print HID descriptor.
|
||||
*
|
||||
* \note TRACE_USBHOST macro must be enabled. See Usb.h for reference.
|
||||
*
|
||||
* \param pDesc Pointer to HID descriptor.
|
||||
*/
|
||||
void HID::PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc)
|
||||
{
|
||||
TRACE_USBHOST(printf("HID::PrintHidDescriptor : bDescLength: %d\r\n", pDesc->bLength);)
|
||||
TRACE_USBHOST(printf("HID::PrintHidDescriptor : bDescriptorType: %d\r\n", pDesc->bDescriptorType);)
|
||||
TRACE_USBHOST(printf("HID::PrintHidDescriptor : bcdHID: %d\r\n", pDesc->bcdHID);)
|
||||
TRACE_USBHOST(printf("HID::PrintHidDescriptor : bCountryCode: %d\r\n", pDesc->bCountryCode);)
|
||||
TRACE_USBHOST(printf("HID::PrintHidDescriptor : bNumDescriptors: %d\r\n", pDesc->bNumDescriptors);)
|
||||
TRACE_USBHOST(printf("HID::PrintHidDescriptor : bDescrType: %d\r\n", pDesc->bDescrType);)
|
||||
TRACE_USBHOST(printf("HID::PrintHidDescriptor : wDescriptorLength: %d\r\n", pDesc->wDescriptorLength);)
|
||||
}
|
192
libraries/USBHost/src/hidboot.cpp
Normal file
192
libraries/USBHost/src/hidboot.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
#include "hidboot.h"
|
||||
|
||||
/**
|
||||
* \brief Parse HID mouse report.
|
||||
*
|
||||
* \param hid HID device pointer.
|
||||
* \param is_rpt_id True if this is a report ID.
|
||||
* \param len Buffer length.
|
||||
* \param buf Buffer containing report data.
|
||||
*/
|
||||
void MouseReportParser::Parse(HID *hid, bool is_rpt_id, uint32_t len, uint8_t *buf)
|
||||
{
|
||||
MOUSEINFO *pmi = (MOUSEINFO*)buf;
|
||||
|
||||
if (prevState.mouseInfo.bmLeftButton == 0 && pmi->bmLeftButton == 1)
|
||||
OnLeftButtonDown(pmi);
|
||||
|
||||
if (prevState.mouseInfo.bmLeftButton == 1 && pmi->bmLeftButton == 0)
|
||||
OnLeftButtonUp(pmi);
|
||||
|
||||
if (prevState.mouseInfo.bmRightButton == 0 && pmi->bmRightButton == 1)
|
||||
OnRightButtonDown(pmi);
|
||||
|
||||
if (prevState.mouseInfo.bmRightButton == 1 && pmi->bmRightButton == 0)
|
||||
OnRightButtonUp(pmi);
|
||||
|
||||
if (prevState.mouseInfo.bmMiddleButton == 0 && pmi->bmMiddleButton == 1)
|
||||
OnMiddleButtonDown(pmi);
|
||||
|
||||
if (prevState.mouseInfo.bmMiddleButton == 1 && pmi->bmMiddleButton == 0)
|
||||
OnMiddleButtonUp(pmi);
|
||||
|
||||
if (prevState.mouseInfo.dX != pmi->dX || prevState.mouseInfo.dY != pmi->dY)
|
||||
OnMouseMove(pmi);
|
||||
|
||||
for (uint32_t i = 0; i < 3; ++i)
|
||||
prevState.bInfo[i] = buf[i];
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Parse HID keyboard report.
|
||||
*
|
||||
* \param hid HID device pointer.
|
||||
* \param is_rpt_id True if this is a report ID.
|
||||
* \param len Buffer length.
|
||||
* \param buf Buffer containing report data.
|
||||
*/
|
||||
void KeyboardReportParser::Parse(HID *hid, bool is_rpt_id, uint32_t len, uint8_t *buf)
|
||||
{
|
||||
// On error - return
|
||||
if (buf[2] == 1)
|
||||
return;
|
||||
|
||||
//KBDINFO *pki = (KBDINFO*)buf;
|
||||
|
||||
for (uint32_t i = 2; i < 8; ++i)
|
||||
{
|
||||
bool down = false;
|
||||
bool up = false;
|
||||
|
||||
for (uint8_t j=2; j<8; j++)
|
||||
{
|
||||
if (buf[i] == prevState.bInfo[j] && buf[i] != 1)
|
||||
down = true;
|
||||
if (buf[j] == prevState.bInfo[i] && prevState.bInfo[i] != 1)
|
||||
up = true;
|
||||
}
|
||||
|
||||
if (!down)
|
||||
{
|
||||
HandleLockingKeys(hid, buf[i]);
|
||||
OnKeyDown(*buf, buf[i]);
|
||||
}
|
||||
|
||||
if (!up)
|
||||
OnKeyUp(prevState.bInfo[0], prevState.bInfo[i]);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < 8; ++i)
|
||||
prevState.bInfo[i] = buf[i];
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Handle keyboard locking keys and manage keyboard leds using USB
|
||||
* report.
|
||||
*
|
||||
* \param hid HID device pointer.
|
||||
* \param key Locking key.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
uint8_t KeyboardReportParser::HandleLockingKeys(HID *hid, uint8_t key)
|
||||
{
|
||||
uint8_t old_keys = kbdLockingKeys.bLeds;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case KEY_NUM_LOCK:
|
||||
kbdLockingKeys.kbdLeds.bmNumLock = ~kbdLockingKeys.kbdLeds.bmNumLock;
|
||||
break;
|
||||
case KEY_CAPS_LOCK:
|
||||
kbdLockingKeys.kbdLeds.bmCapsLock = ~kbdLockingKeys.kbdLeds.bmCapsLock;
|
||||
break;
|
||||
case KEY_SCROLL_LOCK:
|
||||
kbdLockingKeys.kbdLeds.bmScrollLock = ~kbdLockingKeys.kbdLeds.bmScrollLock;
|
||||
break;
|
||||
}
|
||||
|
||||
if (old_keys != kbdLockingKeys.bLeds && hid)
|
||||
return (hid->SetReport(0, 0/*hid->GetIface()*/, 2, 0, 1, &kbdLockingKeys.bLeds));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8_t KeyboardReportParser::numKeys[] = { '!', '@', '#', '$', '%', '^', '&', '*', '(', ')' };
|
||||
const uint8_t KeyboardReportParser::symKeysUp[] = { '_', '+', '{', '}', '|', '~', ':', '"', '~', '<', '>', '?' };
|
||||
const uint8_t KeyboardReportParser::symKeysLo[] = { '-', '=', '[', ']', '\\', ' ', ';', '\'', '`', ',', '.', '/' };
|
||||
const uint8_t KeyboardReportParser::padKeys[] = { '/', '*', '-', '+', 0x13 };
|
||||
|
||||
/**
|
||||
* \brief Manage keyboard OEM to ASCII conversion.
|
||||
*
|
||||
* \param mod Keyboard modifier.
|
||||
* \param key Key value to convert.
|
||||
*
|
||||
* \return Keyboard corresponding ASCII value on success, 0 otherwise.
|
||||
*/
|
||||
uint8_t KeyboardReportParser::OemToAscii(uint8_t mod, uint8_t key)
|
||||
{
|
||||
uint8_t shift = (mod & 0x22);
|
||||
|
||||
// [a-z]
|
||||
if (key > 0x03 && key < 0x1e)
|
||||
{
|
||||
// Upper case letters
|
||||
if ( (kbdLockingKeys.kbdLeds.bmCapsLock == 0 && (mod & 2)) ||
|
||||
(kbdLockingKeys.kbdLeds.bmCapsLock == 1 && (mod & 2) == 0) )
|
||||
return (key - 4 + 'A');
|
||||
|
||||
// Lower case letters
|
||||
else
|
||||
return (key - 4 + 'a');
|
||||
}
|
||||
// Numbers
|
||||
else if (key > 0x1d && key < 0x27)
|
||||
{
|
||||
if (shift)
|
||||
return (numKeys[key - 0x1e]);
|
||||
else
|
||||
return (key - 0x1e + '1');
|
||||
}
|
||||
// Keypad Numbers
|
||||
else if (key > 0x58 && key < 0x62)
|
||||
{
|
||||
if (kbdLockingKeys.kbdLeds.bmNumLock == 1)
|
||||
return (key - 0x59 + '1');
|
||||
}
|
||||
else if (key > 0x2c && key < 0x39)
|
||||
return ((shift) ? symKeysUp[key-0x2d] : symKeysLo[key-0x2d]);
|
||||
else if (key > 0x53 && key < 0x59)
|
||||
return padKeys[key - 0x54];
|
||||
else
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case KEY_SPACE: return (0x20);
|
||||
case KEY_ENTER: return (0x13);
|
||||
case KEY_ZERO: return ((shift) ? ')' : '0');
|
||||
case KEY_ZERO2: return ((kbdLockingKeys.kbdLeds.bmNumLock == 1) ? '0' : 0);
|
||||
case KEY_PERIOD: return ((kbdLockingKeys.kbdLeds.bmNumLock == 1) ? '.' : 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
553
libraries/USBHost/src/hidboot.h
Normal file
553
libraries/USBHost/src/hidboot.h
Normal file
@ -0,0 +1,553 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
#ifndef HIDBOOT_H_INCLUDED
|
||||
#define HIDBOOT_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
#include "usb_ch9.h"
|
||||
#include "Usb.h"
|
||||
#include "hid.h"
|
||||
#include "Arduino.h"
|
||||
#include "confdescparser.h"
|
||||
|
||||
#define KEY_SPACE 0x2c
|
||||
#define KEY_ZERO 0x27
|
||||
#define KEY_ZERO2 0x62
|
||||
#define KEY_ENTER 0x28
|
||||
#define KEY_PERIOD 0x63
|
||||
|
||||
/**
|
||||
* \brief MOUSEINFO definition.
|
||||
*/
|
||||
struct MOUSEINFO
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t bmLeftButton : 1;
|
||||
uint8_t bmRightButton : 1;
|
||||
uint8_t bmMiddleButton : 1;
|
||||
uint8_t bmDummy : 1;
|
||||
};
|
||||
int8_t dX;
|
||||
int8_t dY;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class MouseReportParser definition.
|
||||
*/
|
||||
class MouseReportParser : public HIDReportParser
|
||||
{
|
||||
union
|
||||
{
|
||||
MOUSEINFO mouseInfo;
|
||||
uint8_t bInfo[3];
|
||||
} prevState;
|
||||
|
||||
public:
|
||||
virtual void Parse(HID *hid, bool is_rpt_id, uint32_t len, uint8_t *buf);
|
||||
|
||||
protected:
|
||||
virtual void OnMouseMove (MOUSEINFO *mi) {};
|
||||
virtual void OnLeftButtonUp (MOUSEINFO *mi) {};
|
||||
virtual void OnLeftButtonDown (MOUSEINFO *mi) {};
|
||||
virtual void OnRightButtonUp (MOUSEINFO *mi) {};
|
||||
virtual void OnRightButtonDown (MOUSEINFO *mi) {};
|
||||
virtual void OnMiddleButtonUp (MOUSEINFO *mi) {};
|
||||
virtual void OnMiddleButtonDown (MOUSEINFO *mi) {};
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief MODIFIERKEYS definition.
|
||||
*/
|
||||
struct MODIFIERKEYS
|
||||
{
|
||||
uint8_t bmLeftCtrl : 1;
|
||||
uint8_t bmLeftShift : 1;
|
||||
uint8_t bmLeftAlt : 1;
|
||||
uint8_t bmLeftGUI : 1;
|
||||
uint8_t bmRightCtrl : 1;
|
||||
uint8_t bmRightShift : 1;
|
||||
uint8_t bmRightAlt : 1;
|
||||
uint8_t bmRightGUI : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief KBDINFO definition.
|
||||
*/
|
||||
struct KBDINFO
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t bmLeftCtrl : 1;
|
||||
uint8_t bmLeftShift : 1;
|
||||
uint8_t bmLeftAlt : 1;
|
||||
uint8_t bmLeftGUI : 1;
|
||||
uint8_t bmRightCtrl : 1;
|
||||
uint8_t bmRightShift : 1;
|
||||
uint8_t bmRightAlt : 1;
|
||||
uint8_t bmRightGUI : 1;
|
||||
};
|
||||
uint8_t bReserved;
|
||||
uint8_t Keys[6];
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief KBDLEDS definition.
|
||||
*/
|
||||
struct KBDLEDS
|
||||
{
|
||||
uint8_t bmNumLock : 1;
|
||||
uint8_t bmCapsLock : 1;
|
||||
uint8_t bmScrollLock : 1;
|
||||
uint8_t bmCompose : 1;
|
||||
uint8_t bmKana : 1;
|
||||
uint8_t bmReserved : 3;
|
||||
};
|
||||
|
||||
#define KEY_NUM_LOCK 0x53
|
||||
|
||||
// Clear compiler warning
|
||||
#ifdef KEY_CAPS_LOCK
|
||||
#undef KEY_CAPS_LOCK
|
||||
#endif
|
||||
|
||||
#define KEY_CAPS_LOCK 0x39
|
||||
#define KEY_SCROLL_LOCK 0x47
|
||||
|
||||
/**
|
||||
* \class KeyboardReportParser definition.
|
||||
*/
|
||||
class KeyboardReportParser : public HIDReportParser
|
||||
{
|
||||
static const uint8_t numKeys[];
|
||||
static const uint8_t symKeysUp[];
|
||||
static const uint8_t symKeysLo[];
|
||||
static const uint8_t padKeys[];
|
||||
|
||||
protected:
|
||||
union
|
||||
{
|
||||
KBDINFO kbdInfo;
|
||||
uint8_t bInfo[sizeof(KBDINFO)];
|
||||
} prevState;
|
||||
|
||||
union
|
||||
{
|
||||
KBDLEDS kbdLeds;
|
||||
uint8_t bLeds;
|
||||
} kbdLockingKeys;
|
||||
|
||||
uint8_t OemToAscii(uint8_t mod, uint8_t key);
|
||||
|
||||
public:
|
||||
KeyboardReportParser() { kbdLockingKeys.bLeds = 0; };
|
||||
|
||||
virtual void Parse(HID *hid, bool is_rpt_id, uint32_t len, uint8_t *buf);
|
||||
|
||||
protected:
|
||||
uint8_t HandleLockingKeys(HID* hid, uint8_t key);
|
||||
|
||||
virtual void OnKeyDown (uint8_t mod, uint8_t key) {};
|
||||
virtual void OnKeyUp (uint8_t mod, uint8_t key) {};
|
||||
};
|
||||
|
||||
#define totalEndpoints 2
|
||||
|
||||
#define HID_MAX_HID_CLASS_DESCRIPTORS 5
|
||||
|
||||
/**
|
||||
* \class HIDBoot definition.
|
||||
*/
|
||||
template <const uint8_t BOOT_PROTOCOL>
|
||||
class HIDBoot : public HID
|
||||
{
|
||||
EpInfo epInfo[totalEndpoints];
|
||||
|
||||
HIDReportParser *pRptParser;
|
||||
|
||||
uint32_t bConfNum; // configuration number
|
||||
uint32_t bIfaceNum; // Interface Number
|
||||
uint32_t bNumIface; // number of interfaces in the configuration
|
||||
uint32_t bNumEP; // total number of EP in the configuration
|
||||
uint32_t qNextPollTime; // next poll time
|
||||
bool bPollEnable; // poll enable flag
|
||||
|
||||
void Initialize();
|
||||
|
||||
virtual HIDReportParser* GetReportParser(uint32_t id) { return pRptParser; };
|
||||
|
||||
public:
|
||||
HIDBoot(USBHost *p);
|
||||
|
||||
virtual bool SetReportParser(uint32_t id, HIDReportParser *prs) { pRptParser = prs; return true; };
|
||||
|
||||
// USBDeviceConfig implementation
|
||||
virtual uint32_t Init(uint32_t parent, uint32_t port, uint32_t lowspeed);
|
||||
virtual uint32_t Release();
|
||||
virtual uint32_t Poll();
|
||||
virtual uint32_t GetAddress() { return bAddress; };
|
||||
|
||||
// UsbConfigXtracter implementation
|
||||
virtual void EndpointXtract(uint32_t conf, uint32_t iface, uint32_t alt, uint32_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief HIDBoot class constructor.
|
||||
*/
|
||||
template <const uint8_t BOOT_PROTOCOL>
|
||||
HIDBoot<BOOT_PROTOCOL>::HIDBoot(USBHost *p) :
|
||||
HID(p),
|
||||
pRptParser(NULL),
|
||||
qNextPollTime(0),
|
||||
bPollEnable(false)
|
||||
{
|
||||
Initialize();
|
||||
|
||||
if (pUsb)
|
||||
pUsb->RegisterDeviceClass(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize HIDBoot class.
|
||||
*/
|
||||
template <const uint8_t BOOT_PROTOCOL>
|
||||
void HIDBoot<BOOT_PROTOCOL>::Initialize()
|
||||
{
|
||||
for (uint32_t i = 0; i < totalEndpoints; ++i)
|
||||
{
|
||||
epInfo[i].deviceEpNum = 0;
|
||||
epInfo[i].hostPipeNum = 0;
|
||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||
epInfo[i].epAttribs = 0;
|
||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
||||
}
|
||||
|
||||
bNumEP = 1;
|
||||
bNumIface = 0;
|
||||
bConfNum = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize connection to an HID device.
|
||||
*
|
||||
* \param parent USB device address of the Parent device.
|
||||
* \param port USB device base address.
|
||||
* \param lowspeed USB device speed.
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
template <const uint8_t BOOT_PROTOCOL>
|
||||
uint32_t HIDBoot<BOOT_PROTOCOL>::Init(uint32_t parent, uint32_t port, uint32_t lowspeed)
|
||||
{
|
||||
const uint32_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR);
|
||||
|
||||
uint8_t buf[constBufSize];
|
||||
uint32_t rcode = 0;
|
||||
UsbDevice *p = 0;
|
||||
EpInfo *oldep_ptr = 0;
|
||||
uint32_t len = 0;
|
||||
|
||||
uint32_t num_of_conf = 0; // number of configurations
|
||||
|
||||
AddressPool &addrPool = pUsb->GetAddressPool();
|
||||
|
||||
TRACE_USBHOST(printf("HIDBoot::Init\r\n");)
|
||||
|
||||
if (bAddress)
|
||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||
|
||||
// Get pointer to pseudo device with address 0 assigned
|
||||
p = addrPool.GetUsbDevicePtr(0);
|
||||
|
||||
if (!p)
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
|
||||
if (!p->epinfo)
|
||||
{
|
||||
TRACE_USBHOST(printf("HIDBoot::Init : epinfo is null!\r\n");)
|
||||
return USB_ERROR_EPINFO_IS_NULL;
|
||||
}
|
||||
|
||||
// Save old pointer to EP_RECORD of address 0
|
||||
oldep_ptr = p->epinfo;
|
||||
|
||||
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
||||
p->epinfo = epInfo;
|
||||
|
||||
p->lowspeed = lowspeed;
|
||||
|
||||
// Get device descriptor
|
||||
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
|
||||
|
||||
if (!rcode)
|
||||
len = (buf[0] > constBufSize) ? constBufSize : buf[0];
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
// Restore p->epinfo
|
||||
p->epinfo = oldep_ptr;
|
||||
|
||||
goto FailGetDevDescr;
|
||||
}
|
||||
|
||||
// Restore p->epinfo
|
||||
p->epinfo = oldep_ptr;
|
||||
|
||||
// Allocate new address according to device class
|
||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||
|
||||
if (!bAddress)
|
||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||
|
||||
// Extract Max Packet Size from the device descriptor
|
||||
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
||||
|
||||
// Assign new address to the device
|
||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
p->lowspeed = false;
|
||||
addrPool.FreeAddress(bAddress);
|
||||
bAddress = 0;
|
||||
TRACE_USBHOST(printf("HIDBoot::Init : setAddr failed with rcode %lu\r\n", rcode);)
|
||||
return rcode;
|
||||
}
|
||||
|
||||
TRACE_USBHOST(printf("HIDBoot::Init : device address is now %lu\r\n", bAddress);)
|
||||
|
||||
p->lowspeed = false;
|
||||
|
||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||
|
||||
if (!p)
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
|
||||
p->lowspeed = lowspeed;
|
||||
|
||||
if (len)
|
||||
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
|
||||
|
||||
if(rcode)
|
||||
goto FailGetDevDescr;
|
||||
|
||||
num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
|
||||
|
||||
// Assign epInfo to epinfo pointer
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||
|
||||
if (rcode)
|
||||
goto FailSetDevTblEntry;
|
||||
|
||||
TRACE_USBHOST(printf("HIDBoot::Init : number of configuration is %lu\r\n", num_of_conf);)
|
||||
|
||||
for (uint32_t i = 0; i < num_of_conf; ++i)
|
||||
{
|
||||
ConfigDescParser<
|
||||
USB_CLASS_HID,
|
||||
HID_BOOT_INTF_SUBCLASS,
|
||||
BOOT_PROTOCOL,
|
||||
CP_MASK_COMPARE_ALL> confDescrParser(this);
|
||||
|
||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||
|
||||
if (bNumEP > 1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (bNumEP < 2)
|
||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||
|
||||
TRACE_USBHOST(printf("HIDBoot::Init : bAddress: %lu\r\n", bAddress);)
|
||||
TRACE_USBHOST(printf("HIDBoot::Init : bNumEP: %lu\r\n", bNumEP);)
|
||||
|
||||
// Assign epInfo to epinfo pointer
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
||||
|
||||
TRACE_USBHOST(printf("HIDBoot::Init : bConfNum: %lu\r\n", bConfNum);)
|
||||
|
||||
// Set Configuration Value
|
||||
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
||||
|
||||
if (rcode)
|
||||
goto FailSetConfDescr;
|
||||
|
||||
TRACE_USBHOST(printf("HIDBoot::Init : bIfaceNum: %lu\r\n", bIfaceNum);)
|
||||
|
||||
rcode = SetProtocol(bIfaceNum, HID_BOOT_PROTOCOL);
|
||||
|
||||
if (rcode)
|
||||
goto FailSetProtocol;
|
||||
|
||||
if (BOOT_PROTOCOL == 1)
|
||||
{
|
||||
rcode = SetIdle(bIfaceNum, 0, 0);
|
||||
|
||||
if (rcode)
|
||||
goto FailSetIdle;
|
||||
}
|
||||
|
||||
TRACE_USBHOST(printf("HIDBoot::Init : HID device configured successfully\r\n");)
|
||||
|
||||
bPollEnable = true;
|
||||
return 0;
|
||||
|
||||
FailGetDevDescr:
|
||||
TRACE_USBHOST(printf("HIDBoot::Init getDevDescr : ");)
|
||||
goto Fail;
|
||||
|
||||
FailSetDevTblEntry:
|
||||
TRACE_USBHOST(printf("HIDBoot::Init setDevTblEn : ");)
|
||||
goto Fail;
|
||||
|
||||
FailSetProtocol:
|
||||
TRACE_USBHOST(printf("HIDBoot::Init SetProto : ");)
|
||||
goto Fail;
|
||||
|
||||
FailSetIdle:
|
||||
TRACE_USBHOST(printf("HIDBoot::Init SetIdle : ");)
|
||||
goto Fail;
|
||||
|
||||
FailSetConfDescr:
|
||||
TRACE_USBHOST(printf("HIDBoot::Init setConf : ");)
|
||||
goto Fail;
|
||||
|
||||
Fail:
|
||||
TRACE_USBHOST(printf("error code: %lu\r\n", rcode);)
|
||||
Release();
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Extract interrupt-IN endpoint information from configuration
|
||||
* descriptor.
|
||||
*
|
||||
* \param conf Configuration number.
|
||||
* \param iface Interface number.
|
||||
* \param alt Alternate setting.
|
||||
* \param proto Protocol version used.
|
||||
* \param pep Pointer to endpoint descriptor.
|
||||
*/
|
||||
template <const uint8_t BOOT_PROTOCOL>
|
||||
void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint32_t conf, uint32_t iface, uint32_t alt, uint32_t proto, const USB_ENDPOINT_DESCRIPTOR *pep)
|
||||
{
|
||||
// If the first configuration satisfies, the others are not considered.
|
||||
if (bNumEP > 1 && conf != bConfNum)
|
||||
return;
|
||||
|
||||
bConfNum = conf;
|
||||
bIfaceNum = iface;
|
||||
|
||||
uint32_t index = 0;
|
||||
uint32_t pipe = 0;
|
||||
|
||||
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
||||
{
|
||||
index = epInterruptInIndex;
|
||||
|
||||
// Fill in the endpoint info structure
|
||||
epInfo[index].deviceEpNum = (pep->bEndpointAddress & 0x0F);
|
||||
epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
|
||||
epInfo[index].epAttribs = 0;
|
||||
|
||||
TRACE_USBHOST(printf("HIDBoot::EndpointXtract : Found new endpoint\r\n");)
|
||||
TRACE_USBHOST(printf("HIDBoot::EndpointXtract : deviceEpNum: %lu\r\n", epInfo[index].deviceEpNum);)
|
||||
TRACE_USBHOST(printf("HIDBoot::EndpointXtract : maxPktSize: %lu\r\n", epInfo[index].maxPktSize);)
|
||||
TRACE_USBHOST(printf("HIDBoot::EndpointXtract : index: %lu\r\n", index);)
|
||||
|
||||
// Ensure pipe allocation is okay
|
||||
pipe = UHD_Pipe_Alloc(bAddress, epInfo[index].deviceEpNum, UOTGHS_HSTPIPCFG_PTYPE_INTRPT, UOTGHS_HSTPIPCFG_PTOKEN_IN, epInfo[index].maxPktSize, 10, UOTGHS_HSTPIPCFG_PBK_1_BANK);
|
||||
if (pipe == 0)
|
||||
{
|
||||
TRACE_USBHOST(printf("HIDBoot::EndpointXtract : Pipe allocation failure\r\n");)
|
||||
// Enumeration failed
|
||||
return;
|
||||
}
|
||||
|
||||
epInfo[index].hostPipeNum = pipe;
|
||||
|
||||
bNumEP++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Release USB allocated resources (pipes and address).
|
||||
*
|
||||
* \note Release call is made from USBHost.task() on disconnection events.
|
||||
* \note Release call is made from Init() on enumeration failure.
|
||||
*
|
||||
* \return Always 0.
|
||||
*/
|
||||
template <const uint8_t BOOT_PROTOCOL>
|
||||
uint32_t HIDBoot<BOOT_PROTOCOL>::Release()
|
||||
{
|
||||
// Free allocated host pipes
|
||||
UHD_Pipe_Free(epInfo[epInterruptInIndex].hostPipeNum);
|
||||
|
||||
// Free allocated USB address
|
||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||
|
||||
bConfNum = 0;
|
||||
bIfaceNum = 0;
|
||||
bNumEP = 1;
|
||||
bAddress = 0;
|
||||
qNextPollTime = 0;
|
||||
bPollEnable = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Poll USB device activity.
|
||||
*
|
||||
* \note Poll call is periodically made from USBHost.task().
|
||||
*
|
||||
* \return 0 on success, error code otherwise.
|
||||
*/
|
||||
template <const uint8_t BOOT_PROTOCOL>
|
||||
uint32_t HIDBoot<BOOT_PROTOCOL>::Poll()
|
||||
{
|
||||
uint32_t rcode = 0;
|
||||
|
||||
if (!bPollEnable)
|
||||
return 0;
|
||||
|
||||
if (qNextPollTime <= millis())
|
||||
{
|
||||
qNextPollTime = millis() + 10;
|
||||
|
||||
const uint32_t const_buff_len = 16;
|
||||
uint8_t buf[const_buff_len];
|
||||
|
||||
uint32_t read = epInfo[epInterruptInIndex].maxPktSize;
|
||||
|
||||
rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].deviceEpNum, &read, buf);
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
return rcode;
|
||||
}
|
||||
|
||||
if (pRptParser)
|
||||
pRptParser->Parse((HID*)this, 0, (uint32_t)read, buf);
|
||||
}
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
#endif /* HIDBOOT_H_INCLUDED */
|
976
libraries/USBHost/src/hidusagestr.h
Normal file
976
libraries/USBHost/src/hidusagestr.h
Normal file
@ -0,0 +1,976 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
#ifndef HIDUSAGESTR_H_INCLUDED
|
||||
#define HIDUSAGESTR_H_INCLUDED
|
||||
|
||||
const char pstrSpace [] = " ";
|
||||
const char pstrCRLF [] = "\r\n";
|
||||
const char pstrSingleTab [] = "\t";
|
||||
const char pstrDoubleTab [] = "\t\t";
|
||||
const char pstrTripleTab [] = "\t\t\t";
|
||||
|
||||
// Usage Page String Titles
|
||||
const char pstrUsagePageUndefined [] = "Undef";
|
||||
const char pstrUsagePageGenericDesktopControls [] = "Gen Desktop Ctrls";
|
||||
const char pstrUsagePageSimulationControls [] = "Simu Ctrls";
|
||||
const char pstrUsagePageVRControls [] = "VR Ctrls";
|
||||
const char pstrUsagePageSportControls [] = "Sport Ctrls";
|
||||
const char pstrUsagePageGameControls [] = "Game Ctrls";
|
||||
const char pstrUsagePageGenericDeviceControls [] = "Gen Dev Ctrls";
|
||||
const char pstrUsagePageKeyboardKeypad [] = "Kbrd/Keypad";
|
||||
const char pstrUsagePageLEDs [] = "LEDs";
|
||||
const char pstrUsagePageButton [] = "Button";
|
||||
const char pstrUsagePageOrdinal [] = "Ordinal";
|
||||
const char pstrUsagePageTelephone [] = "Tel";
|
||||
const char pstrUsagePageConsumer [] = "Consumer";
|
||||
const char pstrUsagePageDigitizer [] = "Digitizer";
|
||||
const char pstrUsagePagePID [] = "PID";
|
||||
const char pstrUsagePageUnicode [] = "Unicode";
|
||||
const char pstrUsagePageAlphaNumericDisplay [] = "Alpha Num Disp";
|
||||
const char pstrUsagePageMedicalInstruments [] = "Medical Instr";
|
||||
const char pstrUsagePageMonitor [] = "Monitor";
|
||||
const char pstrUsagePagePower [] = "Power";
|
||||
const char pstrUsagePageBarCodeScanner [] = "Bar Code Scan";
|
||||
const char pstrUsagePageScale [] = "Scale";
|
||||
const char pstrUsagePageMSRDevices [] = "Magn Stripe Read Dev";
|
||||
const char pstrUsagePagePointOfSale [] = "POS";
|
||||
const char pstrUsagePageCameraControl [] = "Cam Ctrl";
|
||||
const char pstrUsagePageArcade [] = "Arcade";
|
||||
const char pstrUsagePageReserved [] = "Reserved";
|
||||
const char pstrUsagePageVendorDefined [] = "Vendor Def";
|
||||
|
||||
// Generic Desktop Controls Page
|
||||
const char pstrUsagePointer [] = "Pointer";
|
||||
const char pstrUsageMouse [] = "Mouse";
|
||||
const char pstrUsageJoystick [] = "Joystick";
|
||||
const char pstrUsageGamePad [] = "Game Pad";
|
||||
const char pstrUsageKeyboard [] = "Kbrd";
|
||||
const char pstrUsageKeypad [] = "Keypad";
|
||||
const char pstrUsageMultiAxisController [] = "Multi-axis Ctrl";
|
||||
const char pstrUsageTabletPCSystemControls [] = "Tablet PC Sys Ctrls";
|
||||
const char pstrUsageX [] = "X";
|
||||
const char pstrUsageY [] = "Y";
|
||||
const char pstrUsageZ [] = "Z";
|
||||
const char pstrUsageRx [] = "Rx";
|
||||
const char pstrUsageRy [] = "Ry";
|
||||
const char pstrUsageRz [] = "Rz";
|
||||
const char pstrUsageSlider [] = "Slider";
|
||||
const char pstrUsageDial [] = "Dial";
|
||||
const char pstrUsageWheel [] = "Wheel";
|
||||
const char pstrUsageHatSwitch [] = "Hat Switch";
|
||||
const char pstrUsageCountedBuffer [] = "Counted Buf";
|
||||
const char pstrUsageByteCount [] = "Byte Count";
|
||||
const char pstrUsageMotionWakeup [] = "Motion Wakeup";
|
||||
const char pstrUsageStart [] = "Start";
|
||||
const char pstrUsageSelect [] = "Sel";
|
||||
const char pstrUsageVx [] = "Vx";
|
||||
const char pstrUsageVy [] = "Vy";
|
||||
const char pstrUsageVz [] = "Vz";
|
||||
const char pstrUsageVbrx [] = "Vbrx";
|
||||
const char pstrUsageVbry [] = "Vbry";
|
||||
const char pstrUsageVbrz [] = "Vbrz";
|
||||
const char pstrUsageVno [] = "Vno";
|
||||
const char pstrUsageFeatureNotification [] = "Feature Notif";
|
||||
const char pstrUsageResolutionMultiplier [] = "Res Mult";
|
||||
const char pstrUsageSystemControl [] = "Sys Ctrl";
|
||||
const char pstrUsageSystemPowerDown [] = "Sys Pwr Down";
|
||||
const char pstrUsageSystemSleep [] = "Sys Sleep";
|
||||
const char pstrUsageSystemWakeup [] = "Sys Wakeup";
|
||||
const char pstrUsageSystemContextMenu [] = "Sys Context Menu";
|
||||
const char pstrUsageSystemMainMenu [] = "Sys Main Menu";
|
||||
const char pstrUsageSystemAppMenu [] = "Sys App Menu";
|
||||
const char pstrUsageSystemMenuHelp [] = "Sys Menu Help";
|
||||
const char pstrUsageSystemMenuExit [] = "Sys Menu Exit";
|
||||
const char pstrUsageSystemMenuSelect [] = "Sys Menu Select";
|
||||
const char pstrUsageSystemMenuRight [] = "Sys Menu Right";
|
||||
const char pstrUsageSystemMenuLeft [] = "Sys Menu Left";
|
||||
const char pstrUsageSystemMenuUp [] = "Sys Menu Up";
|
||||
const char pstrUsageSystemMenuDown [] = "Sys Menu Down";
|
||||
const char pstrUsageSystemColdRestart [] = "Sys Cold Restart";
|
||||
const char pstrUsageSystemWarmRestart [] = "Sys Warm Restart";
|
||||
const char pstrUsageDPadUp [] = "D-pad Up";
|
||||
const char pstrUsageDPadDown [] = "D-pad Down";
|
||||
const char pstrUsageDPadRight [] = "D-pad Right";
|
||||
const char pstrUsageDPadLeft [] = "D-pad Left";
|
||||
const char pstrUsageSystemDock [] = "Sys Dock";
|
||||
const char pstrUsageSystemUndock [] = "Sys Undock";
|
||||
const char pstrUsageSystemSetup [] = "Sys Setup";
|
||||
const char pstrUsageSystemBreak [] = "Sys Break";
|
||||
const char pstrUsageSystemDebuggerBreak [] = "Sys Dbg Brk";
|
||||
const char pstrUsageApplicationBreak [] = "App Break";
|
||||
const char pstrUsageApplicationDebuggerBreak [] = "App Dbg Brk";
|
||||
const char pstrUsageSystemSpeakerMute [] = "Sys Spk Mute";
|
||||
const char pstrUsageSystemHibernate [] = "Sys Hiber";
|
||||
const char pstrUsageSystemDisplayInvert [] = "Sys Disp Inv";
|
||||
const char pstrUsageSystemDisplayInternal [] = "Sys Disp Int";
|
||||
const char pstrUsageSystemDisplayExternal [] = "Sys Disp Ext";
|
||||
const char pstrUsageSystemDisplayBoth [] = "Sys Disp Both";
|
||||
const char pstrUsageSystemDisplayDual [] = "Sys Disp Dual";
|
||||
const char pstrUsageSystemDisplayToggleIntExt [] = "Sys Disp Tgl Int/Ext";
|
||||
const char pstrUsageSystemDisplaySwapPriSec [] = "Sys Disp Swap Pri/Sec";
|
||||
const char pstrUsageSystemDisplayLCDAutoscale [] = "Sys Disp LCD Autoscale";
|
||||
|
||||
// Simulation Controls Page
|
||||
const char pstrUsageFlightSimulationDevice [] = "Flight Simu Dev";
|
||||
const char pstrUsageAutomobileSimulationDevice [] = "Auto Simu Dev";
|
||||
const char pstrUsageTankSimulationDevice [] = "Tank Simu Dev";
|
||||
const char pstrUsageSpaceshipSimulationDevice [] = "Space Simu Dev";
|
||||
const char pstrUsageSubmarineSimulationDevice [] = "Subm Simu Dev";
|
||||
const char pstrUsageSailingSimulationDevice [] = "Sail Simu Dev";
|
||||
const char pstrUsageMotocicleSimulationDevice [] = "Moto Simu Dev";
|
||||
const char pstrUsageSportsSimulationDevice [] = "Sport Simu Dev";
|
||||
const char pstrUsageAirplaneSimulationDevice [] = "Airp Simu Dev";
|
||||
const char pstrUsageHelicopterSimulationDevice [] = "Heli Simu Dev";
|
||||
const char pstrUsageMagicCarpetSimulationDevice [] = "Magic Carpet Simu Dev";
|
||||
const char pstrUsageBicycleSimulationDevice [] = "Bike Simu Dev";
|
||||
const char pstrUsageFlightControlStick [] = "Flight Ctrl Stick";
|
||||
const char pstrUsageFlightStick [] = "Flight Stick";
|
||||
const char pstrUsageCyclicControl [] = "Cyclic Ctrl";
|
||||
const char pstrUsageCyclicTrim [] = "Cyclic Trim";
|
||||
const char pstrUsageFlightYoke [] = "Flight Yoke";
|
||||
const char pstrUsageTrackControl [] = "Track Ctrl";
|
||||
const char pstrUsageAileron [] = "Aileron";
|
||||
const char pstrUsageAileronTrim [] = "Aileron Trim";
|
||||
const char pstrUsageAntiTorqueControl [] = "Anti-Torque Ctrl";
|
||||
const char pstrUsageAutopilotEnable [] = "Autopilot Enable";
|
||||
const char pstrUsageChaffRelease [] = "Chaff Release";
|
||||
const char pstrUsageCollectiveControl [] = "Collective Ctrl";
|
||||
const char pstrUsageDiveBrake [] = "Dive Brake";
|
||||
const char pstrUsageElectronicCountermeasures [] = "El Countermeasures";
|
||||
const char pstrUsageElevator [] = "Elevator";
|
||||
const char pstrUsageElevatorTrim [] = "Elevator Trim";
|
||||
const char pstrUsageRudder [] = "Rudder";
|
||||
const char pstrUsageThrottle [] = "Throttle";
|
||||
const char pstrUsageFlightCommunications [] = "Flight Comm";
|
||||
const char pstrUsageFlareRelease [] = "Flare Release";
|
||||
const char pstrUsageLandingGear [] = "Landing Gear";
|
||||
const char pstrUsageToeBrake [] = "Toe Brake";
|
||||
const char pstrUsageTrigger [] = "Trigger";
|
||||
const char pstrUsageWeaponsArm [] = "Weapons Arm";
|
||||
const char pstrUsageWeaponsSelect [] = "Weapons Sel";
|
||||
const char pstrUsageWingFlaps [] = "Wing Flaps";
|
||||
const char pstrUsageAccelerator [] = "Accel";
|
||||
const char pstrUsageBrake [] = "Brake";
|
||||
const char pstrUsageClutch [] = "Clutch";
|
||||
const char pstrUsageShifter [] = "Shifter";
|
||||
const char pstrUsageSteering [] = "Steering";
|
||||
const char pstrUsageTurretDirection [] = "Turret Dir";
|
||||
const char pstrUsageBarrelElevation [] = "Barrel Ele";
|
||||
const char pstrUsageDivePlane [] = "Dive Plane";
|
||||
const char pstrUsageBallast [] = "Ballast";
|
||||
const char pstrUsageBicycleCrank [] = "Bicycle Crank";
|
||||
const char pstrUsageHandleBars [] = "Handle Bars";
|
||||
const char pstrUsageFrontBrake [] = "Front Brake";
|
||||
const char pstrUsageRearBrake [] = "Rear Brake";
|
||||
|
||||
// VR Controls Page
|
||||
const char pstrUsageBelt [] = "Belt";
|
||||
const char pstrUsageBodySuit [] = "Body Suit";
|
||||
const char pstrUsageFlexor [] = "Flexor";
|
||||
const char pstrUsageGlove [] = "Glove";
|
||||
const char pstrUsageHeadTracker [] = "Head Track";
|
||||
const char pstrUsageHeadMountedDisplay [] = "Head Disp";
|
||||
const char pstrUsageHandTracker [] = "Hand Track";
|
||||
const char pstrUsageOculometer [] = "Oculometer";
|
||||
const char pstrUsageVest [] = "Vest";
|
||||
const char pstrUsageAnimatronicDevice [] = "Animat Dev";
|
||||
const char pstrUsageStereoEnable [] = "Stereo Enbl";
|
||||
const char pstrUsageDisplayEnable [] = "Display Enbl";
|
||||
|
||||
// Sport Controls Page
|
||||
const char pstrUsageBaseballBat [] = "Baseball Bat";
|
||||
const char pstrUsageGolfClub [] = "Golf Club";
|
||||
const char pstrUsageRowingMachine [] = "Rowing Mach";
|
||||
const char pstrUsageTreadmill [] = "Treadmill";
|
||||
const char pstrUsageOar [] = "Oar";
|
||||
const char pstrUsageSlope [] = "Slope";
|
||||
const char pstrUsageRate [] = "Rate";
|
||||
const char pstrUsageStickSpeed [] = "Stick Speed";
|
||||
const char pstrUsageStickFaceAngle [] = "Stick Face Ang";
|
||||
const char pstrUsageStickHeelToe [] = "Stick Heel/Toe";
|
||||
const char pstrUsageStickFollowThough [] = "Stick Flw Thru";
|
||||
const char pstrUsageStickTempo [] = "Stick Tempo";
|
||||
const char pstrUsageStickType [] = "Stick Type";
|
||||
const char pstrUsageStickHeight [] = "Stick Hght";
|
||||
const char pstrUsagePutter [] = "Putter";
|
||||
const char pstrUsage1Iron [] = "1 Iron";
|
||||
const char pstrUsage2Iron [] = "2 Iron";
|
||||
const char pstrUsage3Iron [] = "3 Iron";
|
||||
const char pstrUsage4Iron [] = "4 Iron";
|
||||
const char pstrUsage5Iron [] = "5 Iron";
|
||||
const char pstrUsage6Iron [] = "6 Iron";
|
||||
const char pstrUsage7Iron [] = "7 Iron";
|
||||
const char pstrUsage8Iron [] = "8 Iron";
|
||||
const char pstrUsage9Iron [] = "9 Iron";
|
||||
const char pstrUsage10Iron [] = "10 Iron";
|
||||
const char pstrUsage11Iron [] = "11 Iron";
|
||||
const char pstrUsageSandWedge [] = "Sand Wedge";
|
||||
const char pstrUsageLoftWedge [] = "Loft Wedge";
|
||||
const char pstrUsagePowerWedge [] = "Pwr Wedge";
|
||||
const char pstrUsage1Wood [] = "1 Wood";
|
||||
const char pstrUsage3Wood [] = "3 Wood";
|
||||
const char pstrUsage5Wood [] = "5 Wood";
|
||||
const char pstrUsage7Wood [] = "7 Wood";
|
||||
const char pstrUsage9Wood [] = "9 Wood";
|
||||
|
||||
// Game Controls Page
|
||||
const char pstrUsage3DGameController [] = "3D Game Ctrl";
|
||||
const char pstrUsagePinballDevice [] = "Pinball Dev";
|
||||
const char pstrUsageGunDevice [] = "Gun Dev";
|
||||
const char pstrUsagePointOfView [] = "POV";
|
||||
const char pstrUsageTurnRightLeft [] = "Turn Right Left";
|
||||
const char pstrUsagePitchForwardBackward [] = "Pitch Fwd/Back";
|
||||
const char pstrUsageRollRightLeft [] = "Roll Right/Left";
|
||||
const char pstrUsageMoveRightLeft [] = "Move Right/Left";
|
||||
const char pstrUsageMoveForwardBackward [] = "Move Fwd/Back";
|
||||
const char pstrUsageMoveUpDown [] = "Move Up/Down";
|
||||
const char pstrUsageLeanRightLeft [] = "Lean Right/Left";
|
||||
const char pstrUsageLeanForwardBackward [] = "Lean Fwd/Back";
|
||||
const char pstrUsageHeightOfPOV [] = "Height of POV";
|
||||
const char pstrUsageFlipper [] = "Flipper";
|
||||
const char pstrUsageSecondaryFlipper [] = "Second Flipper";
|
||||
const char pstrUsageBump [] = "Bump";
|
||||
const char pstrUsageNewGame [] = "New Game";
|
||||
const char pstrUsageShootBall [] = "Shoot Ball";
|
||||
const char pstrUsagePlayer [] = "Player";
|
||||
const char pstrUsageGunBolt [] = "Gun Bolt";
|
||||
const char pstrUsageGunClip [] = "Gun Clip";
|
||||
const char pstrUsageGunSelector [] = "Gun Sel";
|
||||
const char pstrUsageGunSingleShot [] = "Gun Sngl Shot";
|
||||
const char pstrUsageGunBurst [] = "Gun Burst";
|
||||
const char pstrUsageGunAutomatic [] = "Gun Auto";
|
||||
const char pstrUsageGunSafety [] = "Gun Safety";
|
||||
const char pstrUsageGamepadFireJump [] = "Gamepad Fire/Jump";
|
||||
const char pstrUsageGamepadTrigger [] = "Gamepad Trig";
|
||||
|
||||
// Generic Device Controls Page
|
||||
const char pstrUsageBatteryStrength [] = "Bat Strength";
|
||||
const char pstrUsageWirelessChannel [] = "Wireless Ch";
|
||||
const char pstrUsageWirelessID [] = "Wireless ID";
|
||||
const char pstrUsageDiscoverWirelessControl [] = "Discover Wireless Ctrl";
|
||||
const char pstrUsageSecurityCodeCharEntered [] = "Sec Code Char Entrd";
|
||||
const char pstrUsageSecurityCodeCharErased [] = "Sec Code Char Erased";
|
||||
const char pstrUsageSecurityCodeCleared [] = "Sec Code Cleared";
|
||||
|
||||
// LED Page
|
||||
const char pstrUsageNumLock [] = "Num Lock";
|
||||
const char pstrUsageCapsLock [] = "Caps Lock";
|
||||
const char pstrUsageScrollLock [] = "Scroll Lock";
|
||||
const char pstrUsageCompose [] = "Compose";
|
||||
const char pstrUsageKana [] = "Kana";
|
||||
const char pstrUsagePower [] = "Pwr";
|
||||
const char pstrUsageShift [] = "Shift";
|
||||
const char pstrUsageDoNotDisturb [] = "DND";
|
||||
const char pstrUsageMute [] = "Mute";
|
||||
const char pstrUsageToneEnable [] = "Tone Enbl";
|
||||
const char pstrUsageHighCutFilter [] = "High Cut Fltr";
|
||||
const char pstrUsageLowCutFilter [] = "Low Cut Fltr";
|
||||
const char pstrUsageEqualizerEnable [] = "Eq Enbl";
|
||||
const char pstrUsageSoundFieldOn [] = "Sound Field On";
|
||||
const char pstrUsageSurroundOn [] = "Surround On";
|
||||
const char pstrUsageRepeat [] = "Repeat";
|
||||
const char pstrUsageStereo [] = "Stereo";
|
||||
const char pstrUsageSamplingRateDetect [] = "Smpl Rate Detect";
|
||||
const char pstrUsageSpinning [] = "Spinning";
|
||||
const char pstrUsageCAV [] = "CAV";
|
||||
const char pstrUsageCLV [] = "CLV";
|
||||
const char pstrUsageRecordingFormatDetect [] = "Rec Format Detect";
|
||||
const char pstrUsageOffHook [] = "Off Hook";
|
||||
const char pstrUsageRing [] = "Ring";
|
||||
const char pstrUsageMessageWaiting [] = "Msg Wait";
|
||||
const char pstrUsageDataMode [] = "Data Mode";
|
||||
const char pstrUsageBatteryOperation [] = "Bat Op";
|
||||
const char pstrUsageBatteryOK [] = "Bat OK";
|
||||
const char pstrUsageBatteryLow [] = "Bat Low";
|
||||
const char pstrUsageSpeaker [] = "Speaker";
|
||||
const char pstrUsageHeadSet [] = "Head Set";
|
||||
const char pstrUsageHold [] = "Hold";
|
||||
const char pstrUsageMicrophone [] = "Mic";
|
||||
const char pstrUsageCoverage [] = "Coverage";
|
||||
const char pstrUsageNightMode [] = "Night Mode";
|
||||
const char pstrUsageSendCalls [] = "Send Calls";
|
||||
const char pstrUsageCallPickup [] = "Call Pickup";
|
||||
const char pstrUsageConference [] = "Conf";
|
||||
const char pstrUsageStandBy [] = "Stand-by";
|
||||
const char pstrUsageCameraOn [] = "Cam On";
|
||||
const char pstrUsageCameraOff [] = "Cam Off";
|
||||
const char pstrUsageOnLine [] = "On-Line";
|
||||
const char pstrUsageOffLine [] = "Off-Line";
|
||||
const char pstrUsageBusy [] = "Busy";
|
||||
const char pstrUsageReady [] = "Ready";
|
||||
const char pstrUsagePaperOut [] = "Paper Out";
|
||||
const char pstrUsagePaperJam [] = "Paper Jam";
|
||||
const char pstrUsageRemote [] = "Remote";
|
||||
const char pstrUsageForward [] = "Fwd";
|
||||
const char pstrUsageReverse [] = "Rev";
|
||||
const char pstrUsageStop [] = "Stop";
|
||||
const char pstrUsageRewind [] = "Rewind";
|
||||
const char pstrUsageFastForward [] = "Fast Fwd";
|
||||
const char pstrUsagePlay [] = "Play";
|
||||
const char pstrUsagePause [] = "Pause";
|
||||
const char pstrUsageRecord [] = "Rec";
|
||||
const char pstrUsageError [] = "Error";
|
||||
const char pstrUsageSelectedIndicator [] = "Usage Sel Ind";
|
||||
const char pstrUsageInUseIndicator [] = "Usage In Use Ind";
|
||||
const char pstrUsageMultiModeIndicator [] = "Usage Multi Mode Ind";
|
||||
const char pstrUsageIndicatorOn [] = "Ind On";
|
||||
const char pstrUsageIndicatorFlash [] = "Ind Flash";
|
||||
const char pstrUsageIndicatorSlowBlink [] = "Ind Slow Blk";
|
||||
const char pstrUsageIndicatorFastBlink [] = "Ind Fast Blk";
|
||||
const char pstrUsageIndicatorOff [] = "Ind Off";
|
||||
const char pstrUsageFlashOnTime [] = "Flash On Time";
|
||||
const char pstrUsageSlowBlinkOnTime [] = "Slow Blk On Time";
|
||||
const char pstrUsageSlowBlinkOffTime [] = "Slow Blk Off Time";
|
||||
const char pstrUsageFastBlinkOnTime [] = "Fast Blk On Time";
|
||||
const char pstrUsageFastBlinkOffTime [] = "Fast Blk Off Time";
|
||||
const char pstrUsageIndicatorColor [] = "Usage Ind Color";
|
||||
const char pstrUsageIndicatorRed [] = "Ind Red";
|
||||
const char pstrUsageIndicatorGreen [] = "Ind Green";
|
||||
const char pstrUsageIndicatorAmber [] = "Ind Amber";
|
||||
const char pstrUsageGenericIndicator [] = "Gen Ind";
|
||||
const char pstrUsageSystemSuspend [] = "Sys Suspend";
|
||||
const char pstrUsageExternalPowerConnected [] = "Ext Pwr Conn";
|
||||
|
||||
// Telephony Usage Page
|
||||
const char pstrUsagePhone [] = "Phone";
|
||||
const char pstrUsageAnsweringMachine [] = "Answ Mach";
|
||||
const char pstrUsageMessageControls [] = "Msg Ctrls";
|
||||
const char pstrUsageHandset [] = "Handset";
|
||||
const char pstrUsageHeadset [] = "Headset";
|
||||
const char pstrUsageTelephonyKeyPad [] = "Tel Key Pad";
|
||||
const char pstrUsageProgrammableButton [] = "Prog Button";
|
||||
const char pstrUsageHookSwitch [] = "Hook Sw";
|
||||
const char pstrUsageFlash [] = "Flash";
|
||||
const char pstrUsageFeature [] = "Feature";
|
||||
//const char pstrUsageHold [] = "Hold";
|
||||
const char pstrUsageRedial [] = "Redial";
|
||||
const char pstrUsageTransfer [] = "Transfer";
|
||||
const char pstrUsageDrop [] = "Drop";
|
||||
const char pstrUsagePark [] = "Park";
|
||||
const char pstrUsageForwardCalls [] = "Fwd Calls";
|
||||
const char pstrUsageAlternateFunction [] = "Alt Func";
|
||||
const char pstrUsageLine [] = "Line";
|
||||
const char pstrUsageSpeakerPhone [] = "Spk Phone";
|
||||
//const char pstrUsageConference [] = "Conference";
|
||||
const char pstrUsageRingEnable [] = "Ring Enbl";
|
||||
const char pstrUsageRingSelect [] = "Ring Sel";
|
||||
const char pstrUsagePhoneMute [] = "Phone Mute";
|
||||
const char pstrUsageCallerID [] = "Caller ID";
|
||||
const char pstrUsageSend [] = "Send";
|
||||
const char pstrUsageSpeedDial [] = "Speed Dial";
|
||||
const char pstrUsageStoreNumber [] = "Store Num";
|
||||
const char pstrUsageRecallNumber [] = "Recall Num";
|
||||
const char pstrUsagePhoneDirectory [] = "Phone Dir";
|
||||
const char pstrUsageVoiceMail [] = "Voice Mail";
|
||||
const char pstrUsageScreenCalls [] = "Screen Calls";
|
||||
//const char pstrUsageDoNotDisturb [] = "Do Not Disturb";
|
||||
const char pstrUsageMessage [] = "Msg";
|
||||
const char pstrUsageAnswerOnOff [] = "Answer On/Off";
|
||||
const char pstrUsageInsideDialTone [] = "Inside Dial Tone";
|
||||
const char pstrUsageOutsideDialTone [] = "Outside Dial Tone";
|
||||
const char pstrUsageInsideRingTone [] = "Inside Ring Tone";
|
||||
const char pstrUsageOutsideRingTone [] = "Outside Ring Tone";
|
||||
const char pstrUsagePriorityRingTone [] = "Prior Ring Tone";
|
||||
const char pstrUsageInsideRingback [] = "Inside Ringback";
|
||||
const char pstrUsagePriorityRingback [] = "Priority Ringback";
|
||||
const char pstrUsageLineBusyTone [] = "Ln Busy Tone";
|
||||
const char pstrUsageReorderTone [] = "Reorder Tone";
|
||||
const char pstrUsageCallWaitingTone [] = "Call Wait Tone";
|
||||
const char pstrUsageConfirmationTone1 [] = "Cnfrm Tone1";
|
||||
const char pstrUsageConfirmationTone2 [] = "Cnfrm Tone2";
|
||||
const char pstrUsageTonesOff [] = "Tones Off";
|
||||
const char pstrUsageOutsideRingback [] = "Outside Ringback";
|
||||
const char pstrUsageRinger [] = "Ringer";
|
||||
const char pstrUsagePhoneKey0 [] = "0";
|
||||
const char pstrUsagePhoneKey1 [] = "1";
|
||||
const char pstrUsagePhoneKey2 [] = "2";
|
||||
const char pstrUsagePhoneKey3 [] = "3";
|
||||
const char pstrUsagePhoneKey4 [] = "4";
|
||||
const char pstrUsagePhoneKey5 [] = "5";
|
||||
const char pstrUsagePhoneKey6 [] = "6";
|
||||
const char pstrUsagePhoneKey7 [] = "7";
|
||||
const char pstrUsagePhoneKey8 [] = "8";
|
||||
const char pstrUsagePhoneKey9 [] = "9";
|
||||
const char pstrUsagePhoneKeyStar [] = "*";
|
||||
const char pstrUsagePhoneKeyPound [] = "#";
|
||||
const char pstrUsagePhoneKeyA [] = "A";
|
||||
const char pstrUsagePhoneKeyB [] = "B";
|
||||
const char pstrUsagePhoneKeyC [] = "C";
|
||||
const char pstrUsagePhoneKeyD [] = "D";
|
||||
|
||||
// Consumer Usage Page
|
||||
const char pstrUsageConsumerControl [] = "Consumer Ctrl";
|
||||
const char pstrUsageNumericKeyPad [] = "Num Key Pad";
|
||||
//const char pstrUsageProgrammableButton [] = "Prog Btn";
|
||||
//const char pstrUsageMicrophone [] = "Mic";
|
||||
const char pstrUsageHeadphone [] = "Headphone";
|
||||
const char pstrUsageGraphicEqualizer [] = "Graph Eq";
|
||||
const char pstrUsagePlus10 [] = "+10";
|
||||
const char pstrUsagePlus100 [] = "+100";
|
||||
const char pstrUsageAMPM [] = "AM/PM";
|
||||
//const char pstrUsagePower [] = "Pwr";
|
||||
const char pstrUsageReset [] = "Reset";
|
||||
const char pstrUsageSleep [] = "Sleep";
|
||||
const char pstrUsageSleepAfter [] = "Sleep After";
|
||||
const char pstrUsageSleepMode [] = "Sleep Mode";
|
||||
const char pstrUsageIllumination [] = "Illumin";
|
||||
const char pstrUsageFunctionButtons [] = "Func Btns";
|
||||
const char pstrUsageMenu [] = "Menu";
|
||||
const char pstrUsageMenuPick [] = "Menu Pick";
|
||||
const char pstrUsageMenuUp [] = "Menu Up";
|
||||
const char pstrUsageMenuDown [] = "Menu Down";
|
||||
const char pstrUsageMenuLeft [] = "Menu Left";
|
||||
const char pstrUsageMenuRight [] = "Menu Right";
|
||||
const char pstrUsageMenuEscape [] = "Menu Esc";
|
||||
const char pstrUsageMenuValueIncrease [] = "Menu Val Inc";
|
||||
const char pstrUsageMenuValueDecrease [] = "Menu Val Dec";
|
||||
const char pstrUsageDataOnScreen [] = "Data On Scr";
|
||||
const char pstrUsageClosedCaption [] = "Closed Cptn";
|
||||
const char pstrUsageClosedCaptionSelect [] = "Closed Cptn Sel";
|
||||
const char pstrUsageVCRTV [] = "VCR/TV";
|
||||
const char pstrUsageBroadcastMode [] = "Brdcast Mode";
|
||||
const char pstrUsageSnapshot [] = "Snapshot";
|
||||
const char pstrUsageStill [] = "Still";
|
||||
const char pstrUsageSelection [] = "Sel";
|
||||
const char pstrUsageAssignSelection [] = "Assign Sel";
|
||||
const char pstrUsageModeStep [] = "Mode Step";
|
||||
const char pstrUsageRecallLast [] = "Recall Last";
|
||||
const char pstrUsageEnterChannel [] = "Entr Channel";
|
||||
const char pstrUsageOrderMovie [] = "Ord Movie";
|
||||
const char pstrUsageChannel [] = "Channel";
|
||||
const char pstrUsageMediaSelection [] = "Med Sel";
|
||||
const char pstrUsageMediaSelectComputer [] = "Med Sel Comp";
|
||||
const char pstrUsageMediaSelectTV [] = "Med Sel TV";
|
||||
const char pstrUsageMediaSelectWWW [] = "Med Sel WWW";
|
||||
const char pstrUsageMediaSelectDVD [] = "Med Sel DVD";
|
||||
const char pstrUsageMediaSelectTelephone [] = "Med Sel Tel";
|
||||
const char pstrUsageMediaSelectProgramGuide [] = "Med Sel PG";
|
||||
const char pstrUsageMediaSelectVideoPhone [] = "Med Sel Vid";
|
||||
const char pstrUsageMediaSelectGames [] = "Med Sel Games";
|
||||
const char pstrUsageMediaSelectMessages [] = "Med Sel Msg";
|
||||
const char pstrUsageMediaSelectCD [] = "Med Sel CD";
|
||||
const char pstrUsageMediaSelectVCR [] = "Med Sel VCR";
|
||||
const char pstrUsageMediaSelectTuner [] = "Med Sel Tuner";
|
||||
const char pstrUsageQuit [] = "Quit";
|
||||
const char pstrUsageHelp [] = "Help";
|
||||
const char pstrUsageMediaSelectTape [] = "Med Sel Tape";
|
||||
const char pstrUsageMediaSelectCable [] = "Med Sel Cbl";
|
||||
const char pstrUsageMediaSelectSatellite [] = "Med Sel Sat";
|
||||
const char pstrUsageMediaSelectSecurity [] = "Med Sel Secur";
|
||||
const char pstrUsageMediaSelectHome [] = "Med Sel Home";
|
||||
const char pstrUsageMediaSelectCall [] = "Med Sel Call";
|
||||
const char pstrUsageChannelIncrement [] = "Ch Inc";
|
||||
const char pstrUsageChannelDecrement [] = "Ch Dec";
|
||||
const char pstrUsageMediaSelectSAP [] = "Med Sel SAP";
|
||||
const char pstrUsageVCRPlus [] = "VCR+";
|
||||
const char pstrUsageOnce [] = "Once";
|
||||
const char pstrUsageDaily [] = "Daily";
|
||||
const char pstrUsageWeekly [] = "Weekly";
|
||||
const char pstrUsageMonthly [] = "Monthly";
|
||||
//const char pstrUsagePlay [] = "Play";
|
||||
//const char pstrUsagePause [] = "Pause";
|
||||
//const char pstrUsageRecord [] = "Rec";
|
||||
//const char pstrUsageFastForward [] = "FF";
|
||||
//const char pstrUsageRewind [] = "Rewind";
|
||||
const char pstrUsageScanNextTrack [] = "Next Track";
|
||||
const char pstrUsageScanPreviousTrack [] = "Prev Track";
|
||||
//const char pstrUsageStop [] = "Stop";
|
||||
const char pstrUsageEject [] = "Eject";
|
||||
const char pstrUsageRandomPlay [] = "Random";
|
||||
const char pstrUsageSelectDisk [] = "Sel Disk";
|
||||
const char pstrUsageEnterDisk [] = "Ent Disk";
|
||||
//const char pstrUsageRepeat [] = "Repeat";
|
||||
const char pstrUsageTracking [] = "Tracking";
|
||||
const char pstrUsageTrackNormal [] = "Trk Norm";
|
||||
const char pstrUsageSlowTracking [] = "Slow Trk";
|
||||
const char pstrUsageFrameForward [] = "Frm Fwd";
|
||||
const char pstrUsageFrameBackwards [] = "Frm Back";
|
||||
const char pstrUsageMark [] = "Mark";
|
||||
const char pstrUsageClearMark [] = "Clr Mark";
|
||||
const char pstrUsageRepeatFromMark [] = "Rpt Mark";
|
||||
const char pstrUsageReturnToMark [] = "Ret to Mark";
|
||||
const char pstrUsageSearchMarkForward [] = "Search Mark Fwd";
|
||||
const char pstrUsageSearchMarkBackwards [] = "Search Mark Back";
|
||||
const char pstrUsageCounterReset [] = "Counter Reset";
|
||||
const char pstrUsageShowCounter [] = "Show Counter";
|
||||
const char pstrUsageTrackingIncrement [] = "Track Inc";
|
||||
const char pstrUsageTrackingDecrement [] = "Track Dec";
|
||||
const char pstrUsageStopEject [] = "Stop/Eject";
|
||||
const char pstrUsagePlayPause [] = "Play/Pause";
|
||||
const char pstrUsagePlaySkip [] = "Play/Skip";
|
||||
const char pstrUsageVolume [] = "Vol";
|
||||
const char pstrUsageBalance [] = "Balance";
|
||||
//const char pstrUsageMute [] = "Mute";
|
||||
const char pstrUsageBass [] = "Bass";
|
||||
const char pstrUsageTreble [] = "Treble";
|
||||
const char pstrUsageBassBoost [] = "Bass Boost";
|
||||
const char pstrUsageSurroundMode [] = "Surround";
|
||||
const char pstrUsageLoudness [] = "Loud";
|
||||
const char pstrUsageMPX [] = "MPX";
|
||||
const char pstrUsageVolumeIncrement [] = "Vol Inc";
|
||||
const char pstrUsageVolumeDecrement [] = "Vol Dec";
|
||||
const char pstrUsageSpeedSelect [] = "Speed";
|
||||
const char pstrUsagePlaybackSpeed [] = "Play Speed";
|
||||
const char pstrUsageStandardPlay [] = "Std Play";
|
||||
const char pstrUsageLongPlay [] = "Long Play";
|
||||
const char pstrUsageExtendedPlay [] = "Ext Play";
|
||||
const char pstrUsageSlow [] = "Slow";
|
||||
const char pstrUsageFanEnable [] = "Fan Enbl";
|
||||
const char pstrUsageFanSpeed [] = "Fan Speed";
|
||||
const char pstrUsageLightEnable [] = "Light Enbl";
|
||||
const char pstrUsageLightIlluminationLevel [] = "Light Illum Lev";
|
||||
const char pstrUsageClimateControlEnable [] = "Climate Enbl";
|
||||
const char pstrUsageRoomTemperature [] = "Room Temp";
|
||||
const char pstrUsageSecurityEnable [] = "Secur Enbl";
|
||||
const char pstrUsageFireAlarm [] = "Fire Alm";
|
||||
const char pstrUsagePoliceAlarm [] = "Police Alm";
|
||||
const char pstrUsageProximity [] = "Prox";
|
||||
const char pstrUsageMotion [] = "Motion";
|
||||
const char pstrUsageDuresAlarm [] = "Dures Alm";
|
||||
const char pstrUsageHoldupAlarm [] = "Holdup Alm";
|
||||
const char pstrUsageMedicalAlarm [] = "Med Alm";
|
||||
const char pstrUsageBalanceRight [] = "Balance Right";
|
||||
const char pstrUsageBalanceLeft [] = "Balance Left";
|
||||
const char pstrUsageBassIncrement [] = "Bass Inc";
|
||||
const char pstrUsageBassDecrement [] = "Bass Dec";
|
||||
const char pstrUsageTrebleIncrement [] = "Treble Inc";
|
||||
const char pstrUsageTrebleDecrement [] = "Treble Dec";
|
||||
const char pstrUsageSpeakerSystem [] = "Spk Sys";
|
||||
const char pstrUsageChannelLeft [] = "Ch Left";
|
||||
const char pstrUsageChannelRight [] = "Ch Right";
|
||||
const char pstrUsageChannelCenter [] = "Ch Center";
|
||||
const char pstrUsageChannelFront [] = "Ch Front";
|
||||
const char pstrUsageChannelCenterFront [] = "Ch Cntr Front";
|
||||
const char pstrUsageChannelSide [] = "Ch Side";
|
||||
const char pstrUsageChannelSurround [] = "Ch Surround";
|
||||
const char pstrUsageChannelLowFreqEnhancement [] = "Ch Low Freq Enh";
|
||||
const char pstrUsageChannelTop [] = "Ch Top";
|
||||
const char pstrUsageChannelUnknown [] = "Ch Unk";
|
||||
const char pstrUsageSubChannel [] = "Sub-ch";
|
||||
const char pstrUsageSubChannelIncrement [] = "Sub-ch Inc";
|
||||
const char pstrUsageSubChannelDecrement [] = "Sub-ch Dec";
|
||||
const char pstrUsageAlternateAudioIncrement [] = "Alt Aud Inc";
|
||||
const char pstrUsageAlternateAudioDecrement [] = "Alt Aud Dec";
|
||||
const char pstrUsageApplicationLaunchButtons [] = "App Launch Btns";
|
||||
const char pstrUsageALLaunchButtonConfigTool [] = "AL Launch Conf Tl";
|
||||
const char pstrUsageALProgrammableButton [] = "AL Pgm Btn";
|
||||
const char pstrUsageALConsumerControlConfig [] = "AL Cons Ctrl Cfg";
|
||||
const char pstrUsageALWordProcessor [] = "AL Word Proc";
|
||||
const char pstrUsageALTextEditor [] = "AL Txt Edtr";
|
||||
const char pstrUsageALSpreadsheet [] = "AL Sprdsheet";
|
||||
const char pstrUsageALGraphicsEditor [] = "AL Graph Edtr";
|
||||
const char pstrUsageALPresentationApp [] = "AL Present App";
|
||||
const char pstrUsageALDatabaseApp [] = "AL DB App";
|
||||
const char pstrUsageALEmailReader [] = "AL E-mail Rdr";
|
||||
const char pstrUsageALNewsreader [] = "AL Newsrdr";
|
||||
const char pstrUsageALVoicemail [] = "AL Voicemail";
|
||||
const char pstrUsageALContactsAddressBook [] = "AL Addr Book";
|
||||
const char pstrUsageALCalendarSchedule [] = "AL Clndr/Schdlr";
|
||||
const char pstrUsageALTaskProjectManager [] = "AL Task/Prj Mgr";
|
||||
const char pstrUsageALLogJournalTimecard [] = "AL Log/Jrnl/Tmcrd";
|
||||
const char pstrUsageALCheckbookFinance [] = "AL Chckbook/Fin";
|
||||
const char pstrUsageALCalculator [] = "AL Calc";
|
||||
const char pstrUsageALAVCapturePlayback [] = "AL A/V Capt/Play";
|
||||
const char pstrUsageALLocalMachineBrowser [] = "AL Loc Mach Brow";
|
||||
const char pstrUsageALLANWANBrow [] = "AL LAN/WAN Brow";
|
||||
const char pstrUsageALInternetBrowser [] = "AL I-net Brow";
|
||||
const char pstrUsageALRemoteNetISPConnect [] = "AL Rem Net Con";
|
||||
const char pstrUsageALNetworkConference [] = "AL Net Conf";
|
||||
const char pstrUsageALNetworkChat [] = "AL Net Chat";
|
||||
const char pstrUsageALTelephonyDialer [] = "AL Tel/Dial";
|
||||
const char pstrUsageALLogon [] = "AL Logon";
|
||||
const char pstrUsageALLogoff [] = "AL Logoff";
|
||||
const char pstrUsageALLogonLogoff [] = "AL Logon/Logoff";
|
||||
const char pstrUsageALTermLockScrSav [] = "AL Term Lock/Scr Sav";
|
||||
const char pstrUsageALControlPannel [] = "AL Ctrl Pan";
|
||||
const char pstrUsageALCommandLineProcessorRun [] = "AL Cmd/Run";
|
||||
const char pstrUsageALProcessTaskManager [] = "AL Task Mgr";
|
||||
const char pstrUsageALSelectTaskApplication [] = "AL Sel App";
|
||||
const char pstrUsageALNextTaskApplication [] = "AL Next App";
|
||||
const char pstrUsageALPreviousTaskApplication [] = "AL Prev App";
|
||||
const char pstrUsageALPreemptiveHaltTaskApp [] = "AL Prmpt Halt App";
|
||||
const char pstrUsageALIntegratedHelpCenter [] = "AL Hlp Cntr";
|
||||
const char pstrUsageALDocuments [] = "AL Docs";
|
||||
const char pstrUsageALThesaurus [] = "AL Thsrs";
|
||||
const char pstrUsageALDictionary [] = "AL Dict";
|
||||
const char pstrUsageALDesktop [] = "AL Desktop";
|
||||
const char pstrUsageALSpellCheck [] = "AL Spell Chk";
|
||||
const char pstrUsageALGrammarCheck [] = "AL Gram Chk";
|
||||
const char pstrUsageALWirelessStatus [] = "AL Wireless Sts";
|
||||
const char pstrUsageALKeyboardLayout [] = "AL Kbd Layout";
|
||||
const char pstrUsageALVirusProtection [] = "AL Vir Protect";
|
||||
const char pstrUsageALEncryption [] = "AL Encrypt";
|
||||
const char pstrUsageALScreenSaver [] = "AL Scr Sav";
|
||||
const char pstrUsageALAlarms [] = "AL Alarms";
|
||||
const char pstrUsageALClock [] = "AL Clock";
|
||||
const char pstrUsageALFileBrowser [] = "AL File Brow";
|
||||
const char pstrUsageALPowerStatus [] = "AL Pwr Sts";
|
||||
const char pstrUsageALImageBrowser [] = "AL Img Brow";
|
||||
const char pstrUsageALAudioBrowser [] = "AL Aud Brow";
|
||||
const char pstrUsageALMovieBrowser [] = "AL Mov Brow";
|
||||
const char pstrUsageALDigitalRightsManager [] = "AL Dig Rights Mgr";
|
||||
const char pstrUsageALDigitalWallet [] = "AL Dig Wallet";
|
||||
const char pstrUsageALInstantMessaging [] = "AL Inst Msg";
|
||||
const char pstrUsageALOEMFeaturesBrowser [] = "AL OEM Tips Brow";
|
||||
const char pstrUsageALOEMHelp [] = "AL OEM Hlp";
|
||||
const char pstrUsageALOnlineCommunity [] = "AL Online Com";
|
||||
const char pstrUsageALEntertainmentContentBrow [] = "AL Ent Cont Brow";
|
||||
const char pstrUsageALOnlineShoppingBrowser [] = "AL Online Shop Brow";
|
||||
const char pstrUsageALSmartCardInfoHelp [] = "AL SmartCard Inf";
|
||||
const char pstrUsageALMarketMonitorFinBrowser [] = "AL Market Brow";
|
||||
const char pstrUsageALCustomCorpNewsBrowser [] = "AL Cust Corp News Brow";
|
||||
const char pstrUsageALOnlineActivityBrowser [] = "AL Online Act Brow";
|
||||
const char pstrUsageALResearchSearchBrowser [] = "AL Search Brow";
|
||||
const char pstrUsageALAudioPlayer [] = "AL Aud Player";
|
||||
const char pstrUsageGenericGUIAppControls [] = "Gen GUI App Ctrl";
|
||||
const char pstrUsageACNew [] = "AC New";
|
||||
const char pstrUsageACOpen [] = "AC Open";
|
||||
const char pstrUsageACClose [] = "AC Close";
|
||||
const char pstrUsageACExit [] = "AC Exit";
|
||||
const char pstrUsageACMaximize [] = "AC Max";
|
||||
const char pstrUsageACMinimize [] = "AC Min";
|
||||
const char pstrUsageACSave [] = "AC Save";
|
||||
const char pstrUsageACPrint [] = "AC Print";
|
||||
const char pstrUsageACProperties [] = "AC Prop";
|
||||
const char pstrUsageACUndo [] = "AC Undo";
|
||||
const char pstrUsageACCopy [] = "AC Copy";
|
||||
const char pstrUsageACCut [] = "AC Cut";
|
||||
const char pstrUsageACPaste [] = "AC Paste";
|
||||
const char pstrUsageACSelectAll [] = "AC Sel All";
|
||||
const char pstrUsageACFind [] = "AC Find";
|
||||
const char pstrUsageACFindAndReplace [] = "AC Find/Replace";
|
||||
const char pstrUsageACSearch [] = "AC Search";
|
||||
const char pstrUsageACGoto [] = "AC Goto";
|
||||
const char pstrUsageACHome [] = "AC Home";
|
||||
const char pstrUsageACBack [] = "AC Back";
|
||||
const char pstrUsageACForward [] = "AC Fwd";
|
||||
const char pstrUsageACStop [] = "AC Stop";
|
||||
const char pstrUsageACRefresh [] = "AC Refresh";
|
||||
const char pstrUsageACPreviousLink [] = "AC Prev Link";
|
||||
const char pstrUsageACNextLink [] = "AC Next Link";
|
||||
const char pstrUsageACBookmarks [] = "AC Bkmarks";
|
||||
const char pstrUsageACHistory [] = "AC Hist";
|
||||
const char pstrUsageACSubscriptions [] = "AC Subscr";
|
||||
const char pstrUsageACZoomIn [] = "AC Zoom In";
|
||||
const char pstrUsageACZoomOut [] = "AC Zoom Out";
|
||||
const char pstrUsageACZoom [] = "AC Zoom";
|
||||
const char pstrUsageACFullScreenView [] = "AC Full Scr";
|
||||
const char pstrUsageACNormalView [] = "AC Norm View";
|
||||
const char pstrUsageACViewToggle [] = "AC View Tgl";
|
||||
const char pstrUsageACScrollUp [] = "AC Scroll Up";
|
||||
const char pstrUsageACScrollDown [] = "AC Scroll Down";
|
||||
const char pstrUsageACScroll [] = "AC Scroll";
|
||||
const char pstrUsageACPanLeft [] = "AC Pan Left";
|
||||
const char pstrUsageACPanRight [] = "AC Pan Right";
|
||||
const char pstrUsageACPan [] = "AC Pan";
|
||||
const char pstrUsageACNewWindow [] = "AC New Wnd";
|
||||
const char pstrUsageACTileHoriz [] = "AC Tile Horiz";
|
||||
const char pstrUsageACTileVert [] = "AC Tile Vert";
|
||||
const char pstrUsageACFormat [] = "AC Frmt";
|
||||
const char pstrUsageACEdit [] = "AC Edit";
|
||||
const char pstrUsageACBold [] = "AC Bold";
|
||||
const char pstrUsageACItalics [] = "AC Ital";
|
||||
const char pstrUsageACUnderline [] = "AC Under";
|
||||
const char pstrUsageACStrikethrough [] = "AC Strike";
|
||||
const char pstrUsageACSubscript [] = "AC Sub";
|
||||
const char pstrUsageACSuperscript [] = "AC Super";
|
||||
const char pstrUsageACAllCaps [] = "AC All Caps";
|
||||
const char pstrUsageACRotate [] = "AC Rotate";
|
||||
const char pstrUsageACResize [] = "AC Resize";
|
||||
const char pstrUsageACFlipHorizontal [] = "AC Flp H";
|
||||
const char pstrUsageACFlipVertical [] = "AC Flp V";
|
||||
const char pstrUsageACMirrorHorizontal [] = "AC Mir H";
|
||||
const char pstrUsageACMirrorVertical [] = "AC Mir V";
|
||||
const char pstrUsageACFontSelect [] = "AC Fnt Sel";
|
||||
const char pstrUsageACFontColor [] = "AC Fnt Clr";
|
||||
const char pstrUsageACFontSize [] = "AC Fnt Size";
|
||||
const char pstrUsageACJustifyLeft [] = "AC Just Left";
|
||||
const char pstrUsageACJustifyCenterH [] = "AC Just Cent H";
|
||||
const char pstrUsageACJustifyRight [] = "AC Just Right";
|
||||
const char pstrUsageACJustifyBlockH [] = "AC Just Block H";
|
||||
const char pstrUsageACJustifyTop [] = "AC Just Top";
|
||||
const char pstrUsageACJustifyCenterV [] = "AC Just Cent V";
|
||||
const char pstrUsageACJustifyBottom [] = "AC Just Bot";
|
||||
const char pstrUsageACJustifyBlockV [] = "AC Just Block V";
|
||||
const char pstrUsageACIndentDecrease [] = "AC Indent Dec";
|
||||
const char pstrUsageACIndentIncrease [] = "AC Indent Inc";
|
||||
const char pstrUsageACNumberedList [] = "AC Num List";
|
||||
const char pstrUsageACRestartNumbering [] = "AC Res Num";
|
||||
const char pstrUsageACBulletedList [] = "AC Blt List";
|
||||
const char pstrUsageACPromote [] = "AC Promote";
|
||||
const char pstrUsageACDemote [] = "AC Demote";
|
||||
const char pstrUsageACYes [] = "AC Yes";
|
||||
const char pstrUsageACNo [] = "AC No";
|
||||
const char pstrUsageACCancel [] = "AC Cancel";
|
||||
const char pstrUsageACCatalog [] = "AC Ctlg";
|
||||
const char pstrUsageACBuyChkout [] = "AC Buy";
|
||||
const char pstrUsageACAddToCart [] = "AC Add2Cart";
|
||||
const char pstrUsageACExpand [] = "AC Xpnd";
|
||||
const char pstrUsageACExpandAll [] = "AC Xpand All";
|
||||
const char pstrUsageACCollapse [] = "AC Collapse";
|
||||
const char pstrUsageACCollapseAll [] = "AC Collapse All";
|
||||
const char pstrUsageACPrintPreview [] = "AC Prn Prevw";
|
||||
const char pstrUsageACPasteSpecial [] = "AC Paste Spec";
|
||||
const char pstrUsageACInsertMode [] = "AC Ins Mode";
|
||||
const char pstrUsageACDelete [] = "AC Del";
|
||||
const char pstrUsageACLock [] = "AC Lock";
|
||||
const char pstrUsageACUnlock [] = "AC Unlock";
|
||||
const char pstrUsageACProtect [] = "AC Prot";
|
||||
const char pstrUsageACUnprotect [] = "AC Unprot";
|
||||
const char pstrUsageACAttachComment [] = "AC Attach Cmnt";
|
||||
const char pstrUsageACDeleteComment [] = "AC Del Cmnt";
|
||||
const char pstrUsageACViewComment [] = "AC View Cmnt";
|
||||
const char pstrUsageACSelectWord [] = "AC Sel Word";
|
||||
const char pstrUsageACSelectSentence [] = "AC Sel Sntc";
|
||||
const char pstrUsageACSelectParagraph [] = "AC Sel Para";
|
||||
const char pstrUsageACSelectColumn [] = "AC Sel Col";
|
||||
const char pstrUsageACSelectRow [] = "AC Sel Row";
|
||||
const char pstrUsageACSelectTable [] = "AC Sel Tbl";
|
||||
const char pstrUsageACSelectObject [] = "AC Sel Obj";
|
||||
const char pstrUsageACRedoRepeat [] = "AC Redo";
|
||||
const char pstrUsageACSort [] = "AC Sort";
|
||||
const char pstrUsageACSortAscending [] = "AC Sort Asc";
|
||||
const char pstrUsageACSortDescending [] = "AC Sort Desc";
|
||||
const char pstrUsageACFilter [] = "AC Filt";
|
||||
const char pstrUsageACSetClock [] = "AC Set Clk";
|
||||
const char pstrUsageACViewClock [] = "AC View Clk";
|
||||
const char pstrUsageACSelectTimeZone [] = "AC Sel Time Z";
|
||||
const char pstrUsageACEditTimeZone [] = "AC Edt Time Z";
|
||||
const char pstrUsageACSetAlarm [] = "AC Set Alm";
|
||||
const char pstrUsageACClearAlarm [] = "AC Clr Alm";
|
||||
const char pstrUsageACSnoozeAlarm [] = "AC Snz Alm";
|
||||
const char pstrUsageACResetAlarm [] = "AC Rst Alm";
|
||||
const char pstrUsageACSyncronize [] = "AC Sync";
|
||||
const char pstrUsageACSendReceive [] = "AC Snd/Rcv";
|
||||
const char pstrUsageACSendTo [] = "AC Snd To";
|
||||
const char pstrUsageACReply [] = "AC Reply";
|
||||
const char pstrUsageACReplyAll [] = "AC Reply All";
|
||||
const char pstrUsageACForwardMessage [] = "AC Fwd Msg";
|
||||
const char pstrUsageACSend [] = "AC Snd";
|
||||
const char pstrUsageACAttachFile [] = "AC Att File";
|
||||
const char pstrUsageACUpload [] = "AC Upld";
|
||||
const char pstrUsageACDownload [] = "AC Dnld";
|
||||
const char pstrUsageACSetBorders [] = "AC Set Brd";
|
||||
const char pstrUsageACInsertRow [] = "AC Ins Row";
|
||||
const char pstrUsageACInsertColumn [] = "AC Ins Col";
|
||||
const char pstrUsageACInsertFile [] = "AC Ins File";
|
||||
const char pstrUsageACInsertPicture [] = "AC Ins Pic";
|
||||
const char pstrUsageACInsertObject [] = "AC Ins Obj";
|
||||
const char pstrUsageACInsertSymbol [] = "AC Ins Sym";
|
||||
const char pstrUsageACSaveAndClose [] = "AC Sav&Cls";
|
||||
const char pstrUsageACRename [] = "AC Rename";
|
||||
const char pstrUsageACMerge [] = "AC Merge";
|
||||
const char pstrUsageACSplit [] = "AC Split";
|
||||
const char pstrUsageACDistributeHorizontaly [] = "AC Dist Hor";
|
||||
const char pstrUsageACDistributeVerticaly [] = "AC Dist Ver";
|
||||
|
||||
// Digitaizers
|
||||
const char pstrUsageDigitizer [] = "Digitizer";
|
||||
const char pstrUsagePen [] = "Pen";
|
||||
const char pstrUsageLightPen [] = "Light Pen";
|
||||
const char pstrUsageTouchScreen [] = "Touch Scr";
|
||||
const char pstrUsageTouchPad [] = "Touch Pad";
|
||||
const char pstrUsageWhiteBoard [] = "White Brd";
|
||||
const char pstrUsageCoordinateMeasuringMachine [] = "Coord Meas Mach";
|
||||
const char pstrUsage3DDigitizer [] = "3D Dgtz";
|
||||
const char pstrUsageStereoPlotter [] = "Stereo Plot";
|
||||
const char pstrUsageArticulatedArm [] = "Art Arm";
|
||||
const char pstrUsageArmature [] = "Armature";
|
||||
const char pstrUsageMultiplePointDigitizer [] = "Multi Point Dgtz";
|
||||
const char pstrUsageFreeSpaceWand [] = "Free Space Wand";
|
||||
const char pstrUsageStylus [] = "Stylus";
|
||||
const char pstrUsagePuck [] = "Puck";
|
||||
const char pstrUsageFinger [] = "Finger";
|
||||
const char pstrUsageTipPressure [] = "Tip Press";
|
||||
const char pstrUsageBarrelPressure [] = "Brl Press";
|
||||
const char pstrUsageInRange [] = "In Range";
|
||||
const char pstrUsageTouch [] = "Touch";
|
||||
const char pstrUsageUntouch [] = "Untouch";
|
||||
const char pstrUsageTap [] = "Tap";
|
||||
const char pstrUsageQuality [] = "Qlty";
|
||||
const char pstrUsageDataValid [] = "Data Valid";
|
||||
const char pstrUsageTransducerIndex [] = "Transducer Ind";
|
||||
const char pstrUsageTabletFunctionKeys [] = "Tabl Func Keys";
|
||||
const char pstrUsageProgramChangeKeys [] = "Pgm Chng Keys";
|
||||
//const char pstrUsageBatteryStrength [] = "Bat Strength";
|
||||
const char pstrUsageInvert [] = "Invert";
|
||||
const char pstrUsageXTilt [] = "X Tilt";
|
||||
const char pstrUsageYTilt [] = "Y Tilt";
|
||||
const char pstrUsageAzimuth [] = "Azimuth";
|
||||
const char pstrUsageAltitude [] = "Altitude";
|
||||
const char pstrUsageTwist [] = "Twist";
|
||||
const char pstrUsageTipSwitch [] = "Tip Sw";
|
||||
const char pstrUsageSecondaryTipSwitch [] = "Scnd Tip Sw";
|
||||
const char pstrUsageBarrelSwitch [] = "Brl Sw";
|
||||
const char pstrUsageEraser [] = "Eraser";
|
||||
const char pstrUsageTabletPick [] = "Tbl Pick";
|
||||
|
||||
// Alphanumeric Display Page
|
||||
const char pstrUsageAlphanumericDisplay [] = "Alphanum Disp";
|
||||
const char pstrUsageBitmappedDisplay [] = "Bmp Disp";
|
||||
const char pstrUsageDisplayAttributesReport [] = "Disp Attr Rpt";
|
||||
const char pstrUsageASCIICharacterSet [] = "ASCII chset";
|
||||
const char pstrUsageDataReadBack [] = "Data Rd Back";
|
||||
const char pstrUsageFontReadBack [] = "Fnt Rd Back";
|
||||
const char pstrUsageDisplayControlReport [] = "Disp Ctrl Rpt";
|
||||
const char pstrUsageClearDisplay [] = "Clr Disp";
|
||||
//const char pstrUsageDisplayEnable [] = "Disp Enbl";
|
||||
const char pstrUsageScreenSaverDelay [] = "Scr Sav Delay";
|
||||
const char pstrUsageScreenSaverEnable [] = "Scr Sav Enbl";
|
||||
const char pstrUsageVerticalScroll [] = "V Scroll";
|
||||
const char pstrUsageHorizontalScroll [] = "H Scroll";
|
||||
const char pstrUsageCharacterReport [] = "Char Rpt";
|
||||
const char pstrUsageDisplayData [] = "Disp Data";
|
||||
const char pstrUsageDisplayStatus [] = "Disp Stat";
|
||||
const char pstrUsageStatusNotReady [] = "Stat !Ready";
|
||||
const char pstrUsageStatusReady [] = "Stat Ready";
|
||||
const char pstrUsageErrorNotALoadableCharacter [] = "Err Not Ld Char";
|
||||
const char pstrUsageErrorFotDataCanNotBeRead [] = "Fnt Data Rd Err";
|
||||
const char pstrUsageCursorPositionReport [] = "Cur Pos Rpt";
|
||||
const char pstrUsageRow [] = "Row";
|
||||
const char pstrUsageColumn [] = "Col";
|
||||
const char pstrUsageRows [] = "Rows";
|
||||
const char pstrUsageColumns [] = "Cols";
|
||||
const char pstrUsageCursorPixelPosition [] = "Cur Pix Pos";
|
||||
const char pstrUsageCursorMode [] = "Cur Mode";
|
||||
const char pstrUsageCursorEnable [] = "Cur Enbl";
|
||||
const char pstrUsageCursorBlink [] = "Cur Blnk";
|
||||
const char pstrUsageFontReport [] = "Fnt Rpt";
|
||||
const char pstrUsageFontData [] = "Fnt Data";
|
||||
const char pstrUsageCharacterWidth [] = "Char Wdth";
|
||||
const char pstrUsageCharacterHeight [] = "Char Hght";
|
||||
const char pstrUsageCharacterSpacingHorizontal [] = "Char Space H";
|
||||
const char pstrUsageCharacterSpacingVertical [] = "Char Space V";
|
||||
const char pstrUsageUnicodeCharset [] = "Unicode Char";
|
||||
const char pstrUsageFont7Segment [] = "Fnt 7-seg";
|
||||
const char pstrUsage7SegmentDirectMap [] = "7-seg map";
|
||||
const char pstrUsageFont14Segment [] = "Fnt 14-seg";
|
||||
const char pstrUsage14SegmentDirectMap [] = "14-seg map";
|
||||
const char pstrUsageDisplayBrightness [] = "Disp Bright";
|
||||
const char pstrUsageDisplayContrast [] = "Disp Cntrst";
|
||||
const char pstrUsageCharacterAttribute [] = "Char Attr";
|
||||
const char pstrUsageAttributeReadback [] = "Attr Readbk";
|
||||
const char pstrUsageAttributeData [] = "Attr Data";
|
||||
const char pstrUsageCharAttributeEnhance [] = "Char Attr Enh";
|
||||
const char pstrUsageCharAttributeUnderline [] = "Char Attr Undl";
|
||||
const char pstrUsageCharAttributeBlink [] = "Char Attr Blnk";
|
||||
const char pstrUsageBitmapSizeX [] = "Bmp Size X";
|
||||
const char pstrUsageBitmapSizeY [] = "Bmp Size Y";
|
||||
const char pstrUsageBitDepthFormat [] = "Bit Dpth Fmt";
|
||||
const char pstrUsageDisplayOrientation [] = "Disp Ornt";
|
||||
const char pstrUsagePaletteReport [] = "Pal Rpt";
|
||||
const char pstrUsagePaletteDataSize [] = "Pal Data Size";
|
||||
const char pstrUsagePaletteDataOffset [] = "Pal Data Off";
|
||||
const char pstrUsagePaletteData [] = "Pal Data";
|
||||
const char pstrUsageBlitReport [] = "Blit Rpt";
|
||||
const char pstrUsageBlitRectangleX1 [] = "Blit Rect X1";
|
||||
const char pstrUsageBlitRectangleY1 [] = "Blit Rect Y1";
|
||||
const char pstrUsageBlitRectangleX2 [] = "Blit Rect X2";
|
||||
const char pstrUsageBlitRectangleY2 [] = "Blit Rect Y2";
|
||||
const char pstrUsageBlitData [] = "Blit Data";
|
||||
const char pstrUsageSoftButton [] = "Soft Btn";
|
||||
const char pstrUsageSoftButtonID [] = "Soft Btn ID";
|
||||
const char pstrUsageSoftButtonSide [] = "Soft Btn Side";
|
||||
const char pstrUsageSoftButtonOffset1 [] = "Soft Btn Off1";
|
||||
const char pstrUsageSoftButtonOffset2 [] = "Soft Btn Off2";
|
||||
const char pstrUsageSoftButtonReport [] = "Soft Btn Rpt";
|
||||
|
||||
// Medical Instrument Page
|
||||
const char pstrUsageMedicalUltrasound [] = "Med Ultrasnd";
|
||||
const char pstrUsageVCRAcquisition [] = "VCR/Acq";
|
||||
const char pstrUsageFreezeThaw [] = "Freeze";
|
||||
const char pstrUsageClipStore [] = "Clip Store";
|
||||
const char pstrUsageUpdate [] = "Update";
|
||||
const char pstrUsageNext [] = "Next";
|
||||
const char pstrUsageSave [] = "Save";
|
||||
const char pstrUsagePrint [] = "Print";
|
||||
const char pstrUsageMicrophoneEnable [] = "Mic Enbl";
|
||||
const char pstrUsageCine [] = "Cine";
|
||||
const char pstrUsageTransmitPower [] = "Trans Pwr";
|
||||
//const char pstrUsageVolume [] = "Vol";
|
||||
const char pstrUsageFocus [] = "Focus";
|
||||
const char pstrUsageDepth [] = "Depth";
|
||||
const char pstrUsageSoftStepPrimary [] = "Soft Stp-Pri";
|
||||
const char pstrUsageSoftStepSecondary [] = "Soft Stp-Sec";
|
||||
const char pstrUsageDepthGainCompensation [] = "Dpth Gain Comp";
|
||||
const char pstrUsageZoomSelect [] = "Zoom Sel";
|
||||
const char pstrUsageZoomAdjust [] = "Zoom Adj";
|
||||
const char pstrUsageSpectralDopplerModeSelect [] = "Spec Dop Mode Sel";
|
||||
const char pstrUsageSpectralDopplerModeAdjust [] = "Spec Dop Mode Adj";
|
||||
const char pstrUsageColorDopplerModeSelect [] = "Color Dop Mode Sel";
|
||||
const char pstrUsageColorDopplerModeAdjust [] = "Color Dop Mode Adj";
|
||||
const char pstrUsageMotionModeSelect [] = "Motion Mode Sel";
|
||||
const char pstrUsageMotionModeAdjust [] = "Motion Mode Adj";
|
||||
const char pstrUsage2DModeSelect [] = "2D Mode Sel";
|
||||
const char pstrUsage2DModeAdjust [] = "2D Mode Adj";
|
||||
const char pstrUsageSoftControlSelect [] = "Soft Ctrl Sel";
|
||||
const char pstrUsageSoftControlAdjust [] = "Soft Ctrl Adj";
|
||||
|
||||
//extern const char *usagePageTitles0[15];
|
||||
//const char *usagePageTitles1[];
|
||||
//const char *genDesktopTitles0[];
|
||||
//const char *genDesktopTitles1[];
|
||||
//const char *genDesktopTitles2[];
|
||||
//const char *genDesktopTitles3[];
|
||||
//const char *genDesktopTitles4[];
|
||||
//const char *simuTitles0[];
|
||||
//const char *simuTitles1[];
|
||||
//const char *simuTitles2[];
|
||||
//const char *vrTitles0[];
|
||||
//const char *vrTitles1[];
|
||||
//const char *sportsCtrlTitles0[];
|
||||
//const char *sportsCtrlTitles1[];
|
||||
//const char *sportsCtrlTitles2[];
|
||||
//const char *gameTitles0[];
|
||||
//const char *gameTitles1[];
|
||||
//const char *genDevCtrlTitles[];
|
||||
//const char *ledTitles[];
|
||||
//const char *telTitles0[];
|
||||
//const char *telTitles1[];
|
||||
//const char *telTitles2[];
|
||||
//const char *telTitles3[];
|
||||
//const char *telTitles4[];
|
||||
//const char *telTitles5[];
|
||||
//const char *consTitles0[];
|
||||
//const char *consTitles1[];
|
||||
//const char *consTitles2[];
|
||||
//const char *consTitles3[];
|
||||
//const char *consTitles4[];
|
||||
//const char *consTitles5[];
|
||||
//const char *consTitles6[];
|
||||
//const char *consTitles7[];
|
||||
//const char *consTitles8[];
|
||||
//const char *consTitles9[];
|
||||
//const char *consTitlesA[];
|
||||
//const char *consTitlesB[];
|
||||
//const char *consTitlesC[];
|
||||
//const char *consTitlesD[];
|
||||
//const char *consTitlesE[];
|
||||
//const char *digitTitles0[];
|
||||
//const char *digitTitles1[];
|
||||
//const char *digitTitles2[];
|
||||
//const char *aplphanumTitles0[];
|
||||
//const char *aplphanumTitles1[];
|
||||
//const char *aplphanumTitles2[];
|
||||
//const char *medInstrTitles0[];
|
||||
//const char *medInstrTitles1[];
|
||||
//const char *medInstrTitles2[];
|
||||
//const char *medInstrTitles3[];
|
||||
//const char *medInstrTitles4[];
|
||||
|
||||
#endif /* HIDUSAGESTR_H_INCLUDED */
|
73
libraries/USBHost/src/parsetools.cpp
Normal file
73
libraries/USBHost/src/parsetools.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
#include "parsetools.h"
|
||||
|
||||
bool MultiByteValueParser::Parse(uint8_t **pp, uint32_t *pcntdn)
|
||||
{
|
||||
if (!pBuf)
|
||||
{
|
||||
//Notify(PSTR("Buffer pointer is NULL!\r\n"));
|
||||
return false;
|
||||
}
|
||||
for (; countDown && (*pcntdn); countDown--, (*pcntdn)--, (*pp)++)
|
||||
pBuf[valueSize-countDown] = (**pp);
|
||||
|
||||
if (countDown)
|
||||
return false;
|
||||
|
||||
countDown = valueSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PTPListParser::Parse(uint8_t **pp, uint32_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me)
|
||||
{
|
||||
switch (nStage)
|
||||
{
|
||||
case 0:
|
||||
pBuf->valueSize = lenSize;
|
||||
theParser.Initialize(pBuf);
|
||||
nStage = 1;
|
||||
|
||||
case 1:
|
||||
if (!theParser.Parse(pp, pcntdn))
|
||||
return false;
|
||||
|
||||
arLen = 0;
|
||||
arLen = (pBuf->valueSize >= 4) ? *((uint32_t*)pBuf->pValue) : (uint32_t)(*((uint16_t*)pBuf->pValue));
|
||||
arLenCntdn = arLen;
|
||||
nStage = 2;
|
||||
|
||||
case 2:
|
||||
pBuf->valueSize = valSize;
|
||||
theParser.Initialize(pBuf);
|
||||
nStage = 3;
|
||||
|
||||
case 3:
|
||||
for (; arLenCntdn; arLenCntdn--)
|
||||
{
|
||||
if (!theParser.Parse(pp, pcntdn))
|
||||
return false;
|
||||
|
||||
if (pf)
|
||||
pf(pBuf, (arLen - arLenCntdn), me);
|
||||
}
|
||||
|
||||
nStage = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
143
libraries/USBHost/src/parsetools.h
Normal file
143
libraries/USBHost/src/parsetools.h
Normal file
@ -0,0 +1,143 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
#ifndef PARSETOOLS_H_INCLUDED
|
||||
#define PARSETOOLS_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
#include "Arduino.h"
|
||||
|
||||
struct MultiValueBuffer
|
||||
{
|
||||
uint8_t valueSize;
|
||||
void *pValue;
|
||||
};
|
||||
|
||||
class MultiByteValueParser
|
||||
{
|
||||
uint8_t *pBuf;
|
||||
uint32_t countDown;
|
||||
uint32_t valueSize;
|
||||
|
||||
public:
|
||||
MultiByteValueParser() : pBuf(NULL), countDown(0), valueSize(0) {};
|
||||
|
||||
const uint8_t* GetBuffer() { return pBuf; };
|
||||
|
||||
void Initialize(MultiValueBuffer * const pbuf)
|
||||
{
|
||||
pBuf = (uint8_t*)pbuf->pValue;
|
||||
countDown = valueSize = pbuf->valueSize;
|
||||
};
|
||||
|
||||
bool Parse(uint8_t **pp, uint32_t *pcntdn);
|
||||
};
|
||||
|
||||
class ByteSkipper
|
||||
{
|
||||
uint8_t *pBuf;
|
||||
uint32_t nStage;
|
||||
uint32_t countDown;
|
||||
|
||||
public:
|
||||
ByteSkipper() : pBuf(NULL), nStage(0), countDown(0) {};
|
||||
|
||||
void Initialize(MultiValueBuffer *pbuf)
|
||||
{
|
||||
pBuf = (uint8_t*)pbuf->pValue;
|
||||
countDown = 0;
|
||||
};
|
||||
|
||||
bool Skip(uint8_t **pp, uint32_t *pcntdn, uint32_t bytes_to_skip)
|
||||
{
|
||||
switch (nStage)
|
||||
{
|
||||
case 0:
|
||||
countDown = bytes_to_skip;
|
||||
nStage ++;
|
||||
case 1:
|
||||
for (; countDown && (*pcntdn); countDown--, (*pp)++, (*pcntdn)--);
|
||||
|
||||
if (!countDown)
|
||||
nStage = 0;
|
||||
};
|
||||
return (!countDown);
|
||||
};
|
||||
};
|
||||
|
||||
// Pointer to a callback function triggered for each element of PTP array when used with PTPArrayParser
|
||||
typedef void (*PTP_ARRAY_EL_FUNC)(const MultiValueBuffer * const p, uint32_t count, const void *me);
|
||||
|
||||
class PTPListParser
|
||||
{
|
||||
public:
|
||||
enum ParseMode { modeArray, modeRange/*, modeEnum*/ };
|
||||
|
||||
private:
|
||||
uint32_t nStage;
|
||||
uint32_t enStage;
|
||||
|
||||
uint32_t arLen;
|
||||
uint32_t arLenCntdn;
|
||||
|
||||
uint32_t lenSize; // size of the array length field in bytes
|
||||
uint32_t valSize; // size of the array element in bytes
|
||||
|
||||
MultiValueBuffer *pBuf;
|
||||
|
||||
// The only parser for both size and array element parsing
|
||||
MultiByteValueParser theParser;
|
||||
|
||||
uint32_t /*ParseMode*/ prsMode;
|
||||
|
||||
public:
|
||||
PTPListParser() :
|
||||
nStage(0),
|
||||
enStage(0),
|
||||
arLen(0),
|
||||
arLenCntdn(0),
|
||||
lenSize(0),
|
||||
valSize(0),
|
||||
pBuf(NULL),
|
||||
prsMode(modeArray)
|
||||
{};
|
||||
|
||||
void Initialize(const uint32_t len_size, const uint32_t val_size, MultiValueBuffer * const p, const uint32_t mode = modeArray)
|
||||
{
|
||||
pBuf = p;
|
||||
lenSize = len_size;
|
||||
valSize = val_size;
|
||||
prsMode = mode;
|
||||
|
||||
if (prsMode == modeRange)
|
||||
{
|
||||
arLenCntdn = arLen = 3;
|
||||
nStage = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
arLenCntdn = arLen = 0;
|
||||
nStage = 0;
|
||||
}
|
||||
enStage = 0;
|
||||
theParser.Initialize(p);
|
||||
};
|
||||
|
||||
bool Parse(uint8_t **pp, uint32_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me = NULL);
|
||||
};
|
||||
|
||||
#endif /* PARSETOOLS_H_INCLUDED */
|
176
libraries/USBHost/src/usb_ch9.h
Normal file
176
libraries/USBHost/src/usb_ch9.h
Normal file
@ -0,0 +1,176 @@
|
||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
||||
|
||||
This software may be distributed and modified under the terms of the GNU
|
||||
General Public License version 2 (GPL2) as published by the Free Software
|
||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||
on this software must also be made publicly available under the terms of
|
||||
the GPL2 ("Copyleft").
|
||||
|
||||
Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
/* USB chapter 9 structures */
|
||||
|
||||
#ifndef USB_CH9_H_INCLUDED
|
||||
#define USB_CH9_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Misc.USB constants */
|
||||
#define DEV_DESCR_LEN 18 //device descriptor length
|
||||
#define CONF_DESCR_LEN 9 //configuration descriptor length
|
||||
#define INTR_DESCR_LEN 9 //interface descriptor length
|
||||
#define EP_DESCR_LEN 7 //endpoint descriptor length
|
||||
|
||||
/* Standard Device Requests */
|
||||
|
||||
#define USB_REQUEST_GET_STATUS 0 // Standard Device Request - GET STATUS
|
||||
#define USB_REQUEST_CLEAR_FEATURE 1 // Standard Device Request - CLEAR FEATURE
|
||||
#define USB_REQUEST_SET_FEATURE 3 // Standard Device Request - SET FEATURE
|
||||
#define USB_REQUEST_SET_ADDRESS 5 // Standard Device Request - SET ADDRESS
|
||||
#define USB_REQUEST_GET_DESCRIPTOR 6 // Standard Device Request - GET DESCRIPTOR
|
||||
#define USB_REQUEST_SET_DESCRIPTOR 7 // Standard Device Request - SET DESCRIPTOR
|
||||
#define USB_REQUEST_GET_CONFIGURATION 8 // Standard Device Request - GET CONFIGURATION
|
||||
#define USB_REQUEST_SET_CONFIGURATION 9 // Standard Device Request - SET CONFIGURATION
|
||||
#define USB_REQUEST_GET_INTERFACE 10 // Standard Device Request - GET INTERFACE
|
||||
#define USB_REQUEST_SET_INTERFACE 11 // Standard Device Request - SET INTERFACE
|
||||
#define USB_REQUEST_SYNCH_FRAME 12 // Standard Device Request - SYNCH FRAME
|
||||
|
||||
#define USB_FEATURE_ENDPOINT_HALT 0 // CLEAR/SET FEATURE - Endpoint Halt
|
||||
#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 // CLEAR/SET FEATURE - Device remote wake-up
|
||||
#define USB_FEATURE_TEST_MODE 2 // CLEAR/SET FEATURE - Test mode
|
||||
|
||||
/* Setup Data Constants */
|
||||
|
||||
#define USB_SETUP_HOST_TO_DEVICE 0x00 // Device Request bmRequestType transfer direction - host to device transfer
|
||||
#define USB_SETUP_DEVICE_TO_HOST 0x80 // Device Request bmRequestType transfer direction - device to host transfer
|
||||
#define USB_SETUP_TYPE_STANDARD 0x00 // Device Request bmRequestType type - standard
|
||||
#define USB_SETUP_TYPE_CLASS 0x20 // Device Request bmRequestType type - class
|
||||
#define USB_SETUP_TYPE_VENDOR 0x40 // Device Request bmRequestType type - vendor
|
||||
#define USB_SETUP_RECIPIENT_DEVICE 0x00 // Device Request bmRequestType recipient - device
|
||||
#define USB_SETUP_RECIPIENT_INTERFACE 0x01 // Device Request bmRequestType recipient - interface
|
||||
#define USB_SETUP_RECIPIENT_ENDPOINT 0x02 // Device Request bmRequestType recipient - endpoint
|
||||
#define USB_SETUP_RECIPIENT_OTHER 0x03 // Device Request bmRequestType recipient - other
|
||||
|
||||
/* USB descriptors */
|
||||
|
||||
#define USB_DESCRIPTOR_DEVICE 0x01 // bDescriptorType for a Device Descriptor.
|
||||
#define USB_DESCRIPTOR_CONFIGURATION 0x02 // bDescriptorType for a Configuration Descriptor.
|
||||
#define USB_DESCRIPTOR_STRING 0x03 // bDescriptorType for a String Descriptor.
|
||||
#define USB_DESCRIPTOR_INTERFACE 0x04 // bDescriptorType for an Interface Descriptor.
|
||||
#define USB_DESCRIPTOR_ENDPOINT 0x05 // bDescriptorType for an Endpoint Descriptor.
|
||||
#define USB_DESCRIPTOR_DEVICE_QUALIFIER 0x06 // bDescriptorType for a Device Qualifier.
|
||||
#define USB_DESCRIPTOR_OTHER_SPEED 0x07 // bDescriptorType for a Other Speed Configuration.
|
||||
#define USB_DESCRIPTOR_INTERFACE_POWER 0x08 // bDescriptorType for Interface Power.
|
||||
#define USB_DESCRIPTOR_OTG 0x09 // bDescriptorType for an OTG Descriptor.
|
||||
|
||||
#define HID_DESCRIPTOR_HID 0x21
|
||||
|
||||
|
||||
|
||||
/* OTG SET FEATURE Constants */
|
||||
#define OTG_FEATURE_B_HNP_ENABLE 3 // SET FEATURE OTG - Enable B device to perform HNP
|
||||
#define OTG_FEATURE_A_HNP_SUPPORT 4 // SET FEATURE OTG - A device supports HNP
|
||||
#define OTG_FEATURE_A_ALT_HNP_SUPPORT 5 // SET FEATURE OTG - Another port on the A device supports HNP
|
||||
|
||||
/* USB Endpoint Transfer Types */
|
||||
#define USB_TRANSFER_TYPE_CONTROL 0x00 // Endpoint is a control endpoint.
|
||||
#define USB_TRANSFER_TYPE_ISOCHRONOUS 0x01 // Endpoint is an isochronous endpoint.
|
||||
#define USB_TRANSFER_TYPE_BULK 0x02 // Endpoint is a bulk endpoint.
|
||||
#define USB_TRANSFER_TYPE_INTERRUPT 0x03 // Endpoint is an interrupt endpoint.
|
||||
#define bmUSB_TRANSFER_TYPE 0x03 // bit mask to separate transfer type from ISO attributes
|
||||
|
||||
|
||||
/* Standard Feature Selectors for CLEAR_FEATURE Requests */
|
||||
#define USB_FEATURE_ENDPOINT_STALL 0 // Endpoint recipient
|
||||
#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 // Device recipient
|
||||
#define USB_FEATURE_TEST_MODE 2 // Device recipient
|
||||
|
||||
_Pragma("pack(1)")
|
||||
|
||||
/* descriptor data structures */
|
||||
|
||||
/* Device descriptor structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; // Length of this descriptor.
|
||||
uint8_t bDescriptorType; // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE).
|
||||
uint16_t bcdUSB; // USB Spec Release Number (BCD).
|
||||
uint8_t bDeviceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
|
||||
uint8_t bDeviceSubClass; // Subclass code (assigned by the USB-IF).
|
||||
uint8_t bDeviceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
|
||||
uint8_t bMaxPacketSize0; // Maximum packet size for endpoint 0.
|
||||
uint16_t idVendor; // Vendor ID (assigned by the USB-IF).
|
||||
uint16_t idProduct; // Product ID (assigned by the manufacturer).
|
||||
uint16_t bcdDevice; // Device release number (BCD).
|
||||
uint8_t iManufacturer; // Index of String Descriptor describing the manufacturer.
|
||||
uint8_t iProduct; // Index of String Descriptor describing the product.
|
||||
uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
|
||||
uint8_t bNumConfigurations; // Number of possible configurations.
|
||||
} USB_DEVICE_DESCRIPTOR;
|
||||
|
||||
/* Configuration descriptor structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; // Length of this descriptor.
|
||||
uint8_t bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
|
||||
uint16_t wTotalLength; // Total length of all descriptors for this configuration.
|
||||
uint8_t bNumInterfaces; // Number of interfaces in this configuration.
|
||||
uint8_t bConfigurationValue; // Value of this configuration (1 based).
|
||||
uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
|
||||
uint8_t bmAttributes; // Configuration characteristics.
|
||||
uint8_t bMaxPower; // Maximum power consumed by this configuration.
|
||||
} USB_CONFIGURATION_DESCRIPTOR;
|
||||
|
||||
/* Interface descriptor structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; // Length of this descriptor.
|
||||
uint8_t bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE).
|
||||
uint8_t bInterfaceNumber; // Number of this interface (0 based).
|
||||
uint8_t bAlternateSetting; // Value of this alternate interface setting.
|
||||
uint8_t bNumEndpoints; // Number of endpoints in this interface.
|
||||
uint8_t bInterfaceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
|
||||
uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
|
||||
uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
|
||||
uint8_t iInterface; // Index of String Descriptor describing the interface.
|
||||
} USB_INTERFACE_DESCRIPTOR;
|
||||
|
||||
/* Endpoint descriptor structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; // Length of this descriptor.
|
||||
uint8_t bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT).
|
||||
uint8_t bEndpointAddress; // Endpoint address. Bit 7 indicates direction (0=OUT, 1=IN).
|
||||
uint8_t bmAttributes; // Endpoint transfer type.
|
||||
uint16_t wMaxPacketSize; // Maximum packet size.
|
||||
uint8_t bInterval; // Polling interval in frames.
|
||||
} USB_ENDPOINT_DESCRIPTOR;
|
||||
|
||||
|
||||
/* HID descriptor */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdHID; // HID class specification release
|
||||
uint8_t bCountryCode;
|
||||
uint8_t bNumDescriptors; // Number of additional class specific descriptors
|
||||
uint8_t bDescrType; // Type of class descriptor
|
||||
uint16_t wDescriptorLength; // Total size of the Report descriptor
|
||||
} USB_HID_DESCRIPTOR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bDescrType; // Type of class descriptor
|
||||
uint16_t wDescriptorLength; // Total size of the Report descriptor
|
||||
} HID_CLASS_DESCRIPTOR_LEN_AND_TYPE;
|
||||
|
||||
_Pragma("pack()")
|
||||
|
||||
#endif /* USB_CH9_H_INCLUDED */
|
Reference in New Issue
Block a user