mirror of
https://github.com/arduino/Arduino.git
synced 2025-02-20 14:54:31 +01:00
Removed USBHost copy. It is available through library manager.
This commit is contained in:
parent
dafb39d149
commit
3262783b78
@ -1,25 +0,0 @@
|
||||
= USB Host Library for Arduino =
|
||||
|
||||
The USBHost library allows an Arduino Due board to appear as a USB host, enabling it to communicate with peripherals like USB mice and keyboards.
|
||||
|
||||
For more information about this library please visit us at
|
||||
http://www.arduino.cc/en/Reference/USBHost
|
||||
|
||||
== License ==
|
||||
|
||||
Copyright (c) 2012 Arduino LLC. All right reserved.
|
||||
Copyright (c) 2011 Circuits At Home, LTD. All rights 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
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
|
||||
ADK Terminal Test
|
||||
|
||||
This demonstrates USB Host connectivity between an
|
||||
Android phone and an Arduino Due.
|
||||
|
||||
The ADK for the Arduino Due is a work in progress
|
||||
For additional information on the Arduino ADK visit
|
||||
http://labs.arduino.cc/ADK/Index
|
||||
|
||||
created 27 June 2012
|
||||
by Cristian Maglie
|
||||
|
||||
*/
|
||||
|
||||
#include "variant.h"
|
||||
#include <stdio.h>
|
||||
#include <adk.h>
|
||||
|
||||
// Accessory descriptor. It's how Arduino identifies itself to Android.
|
||||
char applicationName[] = "Arduino_Terminal"; // the app on your phone
|
||||
char accessoryName[] = "Arduino Due"; // your Arduino board
|
||||
char companyName[] = "Arduino SA";
|
||||
|
||||
// Make up anything you want for these
|
||||
char versionNumber[] = "1.0";
|
||||
char serialNumber[] = "1";
|
||||
char url[] = "http://labs.arduino.cc/uploads/ADK/ArduinoTerminal/ThibaultTerminal_ICS_0001.apk";
|
||||
|
||||
USBHost Usb;
|
||||
ADK adk(&Usb, companyName, applicationName, accessoryName, versionNumber, url, serialNumber);
|
||||
|
||||
void setup() {
|
||||
cpu_irq_enable();
|
||||
printf("\r\nADK demo start\r\n");
|
||||
delay(200);
|
||||
}
|
||||
|
||||
#define RCVSIZE 128
|
||||
|
||||
void loop() {
|
||||
uint8_t buf[RCVSIZE];
|
||||
uint32_t nbread = 0;
|
||||
char helloworld[] = "Hello World!\r\n";
|
||||
|
||||
Usb.Task();
|
||||
|
||||
if (adk.isReady()) {
|
||||
/* Write hello string to ADK */
|
||||
adk.write(strlen(helloworld), (uint8_t *)helloworld);
|
||||
|
||||
delay(1000);
|
||||
|
||||
/* Read data from ADK and print to UART */
|
||||
adk.read(&nbread, RCVSIZE, buf);
|
||||
if (nbread > 0) {
|
||||
printf("RCV: ");
|
||||
for (uint32_t i = 0; i < nbread; ++i) {
|
||||
printf("%c", (char)buf[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
Keyboard Controller Example
|
||||
|
||||
Shows the output of a USB Keyboard connected to
|
||||
the Native USB port on an Arduino Due Board.
|
||||
|
||||
created 8 Oct 2012
|
||||
by Cristian Maglie
|
||||
|
||||
http://www.arduino.cc/en/Tutorial/KeyboardController
|
||||
|
||||
This sample code is part of the public domain.
|
||||
*/
|
||||
|
||||
|
||||
// Require keyboard control library
|
||||
#include <KeyboardController.h>
|
||||
|
||||
// Initialize USB Controller
|
||||
USBHost usb;
|
||||
|
||||
// Attach keyboard controller to USB
|
||||
KeyboardController keyboard(usb);
|
||||
|
||||
// This function intercepts key press
|
||||
void keyPressed() {
|
||||
Serial.print("Pressed: ");
|
||||
printKey();
|
||||
}
|
||||
|
||||
// This function intercepts key release
|
||||
void keyReleased() {
|
||||
Serial.print("Released: ");
|
||||
printKey();
|
||||
}
|
||||
|
||||
void printKey() {
|
||||
// getOemKey() returns the OEM-code associated with the key
|
||||
Serial.print(" key:");
|
||||
Serial.print(keyboard.getOemKey());
|
||||
|
||||
// getModifiers() returns a bits field with the modifiers-keys
|
||||
int mod = keyboard.getModifiers();
|
||||
Serial.print(" mod:");
|
||||
Serial.print(mod);
|
||||
|
||||
Serial.print(" => ");
|
||||
|
||||
if (mod & LeftCtrl) {
|
||||
Serial.print("L-Ctrl ");
|
||||
}
|
||||
if (mod & LeftShift) {
|
||||
Serial.print("L-Shift ");
|
||||
}
|
||||
if (mod & Alt) {
|
||||
Serial.print("Alt ");
|
||||
}
|
||||
if (mod & LeftCmd) {
|
||||
Serial.print("L-Cmd ");
|
||||
}
|
||||
if (mod & RightCtrl) {
|
||||
Serial.print("R-Ctrl ");
|
||||
}
|
||||
if (mod & RightShift) {
|
||||
Serial.print("R-Shift ");
|
||||
}
|
||||
if (mod & AltGr) {
|
||||
Serial.print("AltGr ");
|
||||
}
|
||||
if (mod & RightCmd) {
|
||||
Serial.print("R-Cmd ");
|
||||
}
|
||||
|
||||
// getKey() returns the ASCII translation of OEM key
|
||||
// combined with modifiers.
|
||||
Serial.write(keyboard.getKey());
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("Program started");
|
||||
delay(200);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Process USB tasks
|
||||
usb.Task();
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
Mouse Controller Example
|
||||
|
||||
Shows the output of a USB Mouse connected to
|
||||
the Native USB port on an Arduino Due Board.
|
||||
|
||||
created 8 Oct 2012
|
||||
by Cristian Maglie
|
||||
|
||||
http://www.arduino.cc/en/Tutorial/MouseController
|
||||
|
||||
This sample code is part of the public domain.
|
||||
*/
|
||||
|
||||
// Require mouse control library
|
||||
#include <MouseController.h>
|
||||
|
||||
// Initialize USB Controller
|
||||
USBHost usb;
|
||||
|
||||
// Attach mouse controller to USB
|
||||
MouseController mouse(usb);
|
||||
|
||||
// variables for mouse button states
|
||||
boolean leftButton = false;
|
||||
boolean middleButton = false;
|
||||
boolean rightButton = false;
|
||||
|
||||
// This function intercepts mouse movements
|
||||
void mouseMoved() {
|
||||
Serial.print("Move: ");
|
||||
Serial.print(mouse.getXChange());
|
||||
Serial.print(", ");
|
||||
Serial.println(mouse.getYChange());
|
||||
}
|
||||
|
||||
// This function intercepts mouse movements while a button is pressed
|
||||
void mouseDragged() {
|
||||
Serial.print("DRAG: ");
|
||||
Serial.print(mouse.getXChange());
|
||||
Serial.print(", ");
|
||||
Serial.println(mouse.getYChange());
|
||||
}
|
||||
|
||||
// This function intercepts mouse button press
|
||||
void mousePressed() {
|
||||
Serial.print("Pressed: ");
|
||||
if (mouse.getButton(LEFT_BUTTON)) {
|
||||
Serial.print("L");
|
||||
leftButton = true;
|
||||
}
|
||||
if (mouse.getButton(MIDDLE_BUTTON)) {
|
||||
Serial.print("M");
|
||||
middleButton = true;
|
||||
}
|
||||
if (mouse.getButton(RIGHT_BUTTON)) {
|
||||
Serial.print("R");
|
||||
Serial.println();
|
||||
rightButton = true;
|
||||
}
|
||||
}
|
||||
|
||||
// This function intercepts mouse button release
|
||||
void mouseReleased() {
|
||||
Serial.print("Released: ");
|
||||
if (!mouse.getButton(LEFT_BUTTON) && leftButton == true) {
|
||||
Serial.print("L");
|
||||
leftButton = false;
|
||||
}
|
||||
if (!mouse.getButton(MIDDLE_BUTTON) && middleButton == true) {
|
||||
Serial.print("M");
|
||||
middleButton = false;
|
||||
}
|
||||
if (!mouse.getButton(RIGHT_BUTTON) && rightButton == true) {
|
||||
Serial.print("R");
|
||||
rightButton = false;
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("Program started");
|
||||
delay(200);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Process USB tasks
|
||||
usb.Task();
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For USBHost
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
MouseController KEYWORD1 MouseControllerConstructor
|
||||
USBHost KEYWORD1 USBHost
|
||||
KeyboardController KEYWORD1 KeyboardControllerConstructor
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
Task KEYWORD2 USBHostTask
|
||||
mouseMoved KEYWORD2
|
||||
mouseDragged KEYWORD2
|
||||
mousePressed KEYWORD2
|
||||
mouseReleased KEYWORD2
|
||||
getXChange KEYWORD2
|
||||
getYChange KEYWORD2
|
||||
getButton KEYWORD2
|
||||
keyPressed KEYWORD2
|
||||
keyReleased KEYWORD2
|
||||
getModifiers KEYWORD2
|
||||
getKey KEYWORD2
|
||||
getOemKey KEYWORD2
|
||||
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
@ -1,9 +0,0 @@
|
||||
name=USBHost
|
||||
version=1.0.3
|
||||
author=Arduino
|
||||
maintainer=Arduino <info@arduino.cc>
|
||||
sentence=Allows the communication with USB peripherals like mice, keyboards, and thumbdrives. For Arduino DUE only.
|
||||
paragraph=The USBHost library allows an Arduino Due board to appear as a USB host, enabling it to communicate with peripherals like USB mice and keyboards. USBHost does not support devices that are connected through USB hubs. This includes some keyboards that have an internal hub.
|
||||
category=Device Control
|
||||
url=http://www.arduino.cc/en/Reference/USBHost
|
||||
architectures=sam
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2012 Arduino LLC. 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();
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2012 Arduino LLC. 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
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2012 Arduino LLC. 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();
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2012 Arduino LLC. 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
|
@ -1,856 +0,0 @@
|
||||
/* 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;
|
||||
}
|
||||
}
|
@ -1,230 +0,0 @@
|
||||
/* 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 */
|
@ -1,392 +0,0 @@
|
||||
/* 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 */
|
@ -1,405 +0,0 @@
|
||||
/* 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);
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
/* 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 */
|
@ -1,241 +0,0 @@
|
||||
/* 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 */
|
@ -1,202 +0,0 @@
|
||||
/* 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 */
|
@ -1,141 +0,0 @@
|
||||
/* 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);)
|
||||
}
|
@ -1,192 +0,0 @@
|
||||
/* 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;
|
||||
}
|
@ -1,553 +0,0 @@
|
||||
/* 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 */
|
@ -1,976 +0,0 @@
|
||||
/* 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 */
|
@ -1,73 +0,0 @@
|
||||
/* 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;
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
/* 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 */
|
@ -1,176 +0,0 @@
|
||||
/* 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 */
|
Loading…
x
Reference in New Issue
Block a user