USB device stack - modified

Dependents:   shaun_larada

Fork of USBDevice by mbed official

Committer:
setcom_001
Date:
Mon Jul 22 21:16:27 2013 +0000
Revision:
12:a9671b78d24e
docs update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
setcom_001 12:a9671b78d24e 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
setcom_001 12:a9671b78d24e 2 *
setcom_001 12:a9671b78d24e 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
setcom_001 12:a9671b78d24e 4 * and associated documentation files (the "Software"), to deal in the Software without
setcom_001 12:a9671b78d24e 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
setcom_001 12:a9671b78d24e 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
setcom_001 12:a9671b78d24e 7 * Software is furnished to do so, subject to the following conditions:
setcom_001 12:a9671b78d24e 8 *
setcom_001 12:a9671b78d24e 9 * The above copyright notice and this permission notice shall be included in all copies or
setcom_001 12:a9671b78d24e 10 * substantial portions of the Software.
setcom_001 12:a9671b78d24e 11 *
setcom_001 12:a9671b78d24e 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
setcom_001 12:a9671b78d24e 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
setcom_001 12:a9671b78d24e 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
setcom_001 12:a9671b78d24e 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
setcom_001 12:a9671b78d24e 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
setcom_001 12:a9671b78d24e 17 */
setcom_001 12:a9671b78d24e 18
setcom_001 12:a9671b78d24e 19 #include "stdint.h"
setcom_001 12:a9671b78d24e 20 #include "USBMouse.h"
setcom_001 12:a9671b78d24e 21
setcom_001 12:a9671b78d24e 22 bool USBMouse::update( int16_t x, int16_t y, uint8_t button, int8_t z )
setcom_001 12:a9671b78d24e 23 {
setcom_001 12:a9671b78d24e 24 switch ( mouse_type )
setcom_001 12:a9671b78d24e 25 {
setcom_001 12:a9671b78d24e 26 case REL_MOUSE:
setcom_001 12:a9671b78d24e 27 while ( x > 127 )
setcom_001 12:a9671b78d24e 28 {
setcom_001 12:a9671b78d24e 29 if ( !mouseSend( 127, 0, button, z ) )
setcom_001 12:a9671b78d24e 30 {
setcom_001 12:a9671b78d24e 31 return false;
setcom_001 12:a9671b78d24e 32 }
setcom_001 12:a9671b78d24e 33
setcom_001 12:a9671b78d24e 34 x = x - 127;
setcom_001 12:a9671b78d24e 35 }
setcom_001 12:a9671b78d24e 36
setcom_001 12:a9671b78d24e 37 while ( x < -128 )
setcom_001 12:a9671b78d24e 38 {
setcom_001 12:a9671b78d24e 39 if ( !mouseSend( -128, 0, button, z ) )
setcom_001 12:a9671b78d24e 40 {
setcom_001 12:a9671b78d24e 41 return false;
setcom_001 12:a9671b78d24e 42 }
setcom_001 12:a9671b78d24e 43
setcom_001 12:a9671b78d24e 44 x = x + 128;
setcom_001 12:a9671b78d24e 45 }
setcom_001 12:a9671b78d24e 46
setcom_001 12:a9671b78d24e 47 while ( y > 127 )
setcom_001 12:a9671b78d24e 48 {
setcom_001 12:a9671b78d24e 49 if ( !mouseSend( 0, 127, button, z ) )
setcom_001 12:a9671b78d24e 50 {
setcom_001 12:a9671b78d24e 51 return false;
setcom_001 12:a9671b78d24e 52 }
setcom_001 12:a9671b78d24e 53
setcom_001 12:a9671b78d24e 54 y = y - 127;
setcom_001 12:a9671b78d24e 55 }
setcom_001 12:a9671b78d24e 56
setcom_001 12:a9671b78d24e 57 while ( y < -128 )
setcom_001 12:a9671b78d24e 58 {
setcom_001 12:a9671b78d24e 59 if ( !mouseSend( 0, -128, button, z ) )
setcom_001 12:a9671b78d24e 60 {
setcom_001 12:a9671b78d24e 61 return false;
setcom_001 12:a9671b78d24e 62 }
setcom_001 12:a9671b78d24e 63
setcom_001 12:a9671b78d24e 64 y = y + 128;
setcom_001 12:a9671b78d24e 65 }
setcom_001 12:a9671b78d24e 66
setcom_001 12:a9671b78d24e 67 return mouseSend( x, y, button, z );
setcom_001 12:a9671b78d24e 68
setcom_001 12:a9671b78d24e 69 case ABS_MOUSE:
setcom_001 12:a9671b78d24e 70 HID_REPORT report;
setcom_001 12:a9671b78d24e 71 report.data[0] = x & 0xff;
setcom_001 12:a9671b78d24e 72 report.data[1] = ( x >> 8 ) & 0xff;
setcom_001 12:a9671b78d24e 73 report.data[2] = y & 0xff;
setcom_001 12:a9671b78d24e 74 report.data[3] = ( y >> 8 ) & 0xff;
setcom_001 12:a9671b78d24e 75 report.data[4] = -z;
setcom_001 12:a9671b78d24e 76 report.data[5] = button & 0x07;
setcom_001 12:a9671b78d24e 77 report.length = 6;
setcom_001 12:a9671b78d24e 78 return send( &report );
setcom_001 12:a9671b78d24e 79
setcom_001 12:a9671b78d24e 80 default:
setcom_001 12:a9671b78d24e 81 return false;
setcom_001 12:a9671b78d24e 82 }
setcom_001 12:a9671b78d24e 83 }
setcom_001 12:a9671b78d24e 84
setcom_001 12:a9671b78d24e 85 bool USBMouse::mouseSend( int8_t x, int8_t y, uint8_t buttons, int8_t z )
setcom_001 12:a9671b78d24e 86 {
setcom_001 12:a9671b78d24e 87 HID_REPORT report;
setcom_001 12:a9671b78d24e 88 report.data[0] = buttons & 0x07;
setcom_001 12:a9671b78d24e 89 report.data[1] = x;
setcom_001 12:a9671b78d24e 90 report.data[2] = y;
setcom_001 12:a9671b78d24e 91 report.data[3] = -z; // >0 to scroll down, <0 to scroll up
setcom_001 12:a9671b78d24e 92 report.length = 4;
setcom_001 12:a9671b78d24e 93 return send( &report );
setcom_001 12:a9671b78d24e 94 }
setcom_001 12:a9671b78d24e 95
setcom_001 12:a9671b78d24e 96 bool USBMouse::move( int16_t x, int16_t y )
setcom_001 12:a9671b78d24e 97 {
setcom_001 12:a9671b78d24e 98 return update( x, y, button, 0 );
setcom_001 12:a9671b78d24e 99 }
setcom_001 12:a9671b78d24e 100
setcom_001 12:a9671b78d24e 101 bool USBMouse::scroll( int8_t z )
setcom_001 12:a9671b78d24e 102 {
setcom_001 12:a9671b78d24e 103 return update( 0, 0, button, z );
setcom_001 12:a9671b78d24e 104 }
setcom_001 12:a9671b78d24e 105
setcom_001 12:a9671b78d24e 106
setcom_001 12:a9671b78d24e 107 bool USBMouse::doubleClick()
setcom_001 12:a9671b78d24e 108 {
setcom_001 12:a9671b78d24e 109 if ( !click( MOUSE_LEFT ) )
setcom_001 12:a9671b78d24e 110 {
setcom_001 12:a9671b78d24e 111 return false;
setcom_001 12:a9671b78d24e 112 }
setcom_001 12:a9671b78d24e 113
setcom_001 12:a9671b78d24e 114 wait( 0.1 );
setcom_001 12:a9671b78d24e 115 return click( MOUSE_LEFT );
setcom_001 12:a9671b78d24e 116 }
setcom_001 12:a9671b78d24e 117
setcom_001 12:a9671b78d24e 118 bool USBMouse::click( uint8_t button )
setcom_001 12:a9671b78d24e 119 {
setcom_001 12:a9671b78d24e 120 if ( !update( 0, 0, button, 0 ) )
setcom_001 12:a9671b78d24e 121 {
setcom_001 12:a9671b78d24e 122 return false;
setcom_001 12:a9671b78d24e 123 }
setcom_001 12:a9671b78d24e 124
setcom_001 12:a9671b78d24e 125 wait( 0.01 );
setcom_001 12:a9671b78d24e 126 return update( 0, 0, 0, 0 );
setcom_001 12:a9671b78d24e 127 }
setcom_001 12:a9671b78d24e 128
setcom_001 12:a9671b78d24e 129 bool USBMouse::press( uint8_t button_ )
setcom_001 12:a9671b78d24e 130 {
setcom_001 12:a9671b78d24e 131 button = button_ & 0x07;
setcom_001 12:a9671b78d24e 132 return update( 0, 0, button, 0 );
setcom_001 12:a9671b78d24e 133 }
setcom_001 12:a9671b78d24e 134
setcom_001 12:a9671b78d24e 135 bool USBMouse::release( uint8_t button_ )
setcom_001 12:a9671b78d24e 136 {
setcom_001 12:a9671b78d24e 137 button = ( button & ( ~button_ ) ) & 0x07;
setcom_001 12:a9671b78d24e 138 return update( 0, 0, button, 0 );
setcom_001 12:a9671b78d24e 139 }
setcom_001 12:a9671b78d24e 140
setcom_001 12:a9671b78d24e 141
setcom_001 12:a9671b78d24e 142 uint8_t *USBMouse::reportDesc()
setcom_001 12:a9671b78d24e 143 {
setcom_001 12:a9671b78d24e 144 if ( mouse_type == REL_MOUSE )
setcom_001 12:a9671b78d24e 145 {
setcom_001 12:a9671b78d24e 146 static uint8_t reportDescriptor[] =
setcom_001 12:a9671b78d24e 147 {
setcom_001 12:a9671b78d24e 148 USAGE_PAGE( 1 ), 0x01, // Genric Desktop
setcom_001 12:a9671b78d24e 149 USAGE( 1 ), 0x02, // Mouse
setcom_001 12:a9671b78d24e 150 COLLECTION( 1 ), 0x01, // Application
setcom_001 12:a9671b78d24e 151 USAGE( 1 ), 0x01, // Pointer
setcom_001 12:a9671b78d24e 152 COLLECTION( 1 ), 0x00, // Physical
setcom_001 12:a9671b78d24e 153
setcom_001 12:a9671b78d24e 154 REPORT_COUNT( 1 ), 0x03,
setcom_001 12:a9671b78d24e 155 REPORT_SIZE( 1 ), 0x01,
setcom_001 12:a9671b78d24e 156 USAGE_PAGE( 1 ), 0x09, // Buttons
setcom_001 12:a9671b78d24e 157 USAGE_MINIMUM( 1 ), 0x1,
setcom_001 12:a9671b78d24e 158 USAGE_MAXIMUM( 1 ), 0x3,
setcom_001 12:a9671b78d24e 159 LOGICAL_MINIMUM( 1 ), 0x00,
setcom_001 12:a9671b78d24e 160 LOGICAL_MAXIMUM( 1 ), 0x01,
setcom_001 12:a9671b78d24e 161 INPUT( 1 ), 0x02,
setcom_001 12:a9671b78d24e 162 REPORT_COUNT( 1 ), 0x01,
setcom_001 12:a9671b78d24e 163 REPORT_SIZE( 1 ), 0x05,
setcom_001 12:a9671b78d24e 164 INPUT( 1 ), 0x01,
setcom_001 12:a9671b78d24e 165
setcom_001 12:a9671b78d24e 166 REPORT_COUNT( 1 ), 0x03,
setcom_001 12:a9671b78d24e 167 REPORT_SIZE( 1 ), 0x08,
setcom_001 12:a9671b78d24e 168 USAGE_PAGE( 1 ), 0x01,
setcom_001 12:a9671b78d24e 169 USAGE( 1 ), 0x30, // X
setcom_001 12:a9671b78d24e 170 USAGE( 1 ), 0x31, // Y
setcom_001 12:a9671b78d24e 171 USAGE( 1 ), 0x38, // scroll
setcom_001 12:a9671b78d24e 172 LOGICAL_MINIMUM( 1 ), 0x81,
setcom_001 12:a9671b78d24e 173 LOGICAL_MAXIMUM( 1 ), 0x7f,
setcom_001 12:a9671b78d24e 174 INPUT( 1 ), 0x06, // Relative data
setcom_001 12:a9671b78d24e 175
setcom_001 12:a9671b78d24e 176 END_COLLECTION( 0 ),
setcom_001 12:a9671b78d24e 177 END_COLLECTION( 0 ),
setcom_001 12:a9671b78d24e 178 };
setcom_001 12:a9671b78d24e 179 reportLength = sizeof( reportDescriptor );
setcom_001 12:a9671b78d24e 180 return reportDescriptor;
setcom_001 12:a9671b78d24e 181 }
setcom_001 12:a9671b78d24e 182 else if ( mouse_type == ABS_MOUSE )
setcom_001 12:a9671b78d24e 183 {
setcom_001 12:a9671b78d24e 184 static uint8_t reportDescriptor[] =
setcom_001 12:a9671b78d24e 185 {
setcom_001 12:a9671b78d24e 186
setcom_001 12:a9671b78d24e 187 USAGE_PAGE( 1 ), 0x01, // Generic Desktop
setcom_001 12:a9671b78d24e 188 USAGE( 1 ), 0x02, // Mouse
setcom_001 12:a9671b78d24e 189 COLLECTION( 1 ), 0x01, // Application
setcom_001 12:a9671b78d24e 190 USAGE( 1 ), 0x01, // Pointer
setcom_001 12:a9671b78d24e 191 COLLECTION( 1 ), 0x00, // Physical
setcom_001 12:a9671b78d24e 192
setcom_001 12:a9671b78d24e 193 USAGE_PAGE( 1 ), 0x01, // Generic Desktop
setcom_001 12:a9671b78d24e 194 USAGE( 1 ), 0x30, // X
setcom_001 12:a9671b78d24e 195 USAGE( 1 ), 0x31, // Y
setcom_001 12:a9671b78d24e 196 LOGICAL_MINIMUM( 1 ), 0x00, // 0
setcom_001 12:a9671b78d24e 197 LOGICAL_MAXIMUM( 2 ), 0xff, 0x7f, // 32767
setcom_001 12:a9671b78d24e 198 REPORT_SIZE( 1 ), 0x10,
setcom_001 12:a9671b78d24e 199 REPORT_COUNT( 1 ), 0x02,
setcom_001 12:a9671b78d24e 200 INPUT( 1 ), 0x02, // Data, Variable, Absolute
setcom_001 12:a9671b78d24e 201
setcom_001 12:a9671b78d24e 202 USAGE_PAGE( 1 ), 0x01, // Generic Desktop
setcom_001 12:a9671b78d24e 203 USAGE( 1 ), 0x38, // scroll
setcom_001 12:a9671b78d24e 204 LOGICAL_MINIMUM( 1 ), 0x81, // -127
setcom_001 12:a9671b78d24e 205 LOGICAL_MAXIMUM( 1 ), 0x7f, // 127
setcom_001 12:a9671b78d24e 206 REPORT_SIZE( 1 ), 0x08,
setcom_001 12:a9671b78d24e 207 REPORT_COUNT( 1 ), 0x01,
setcom_001 12:a9671b78d24e 208 INPUT( 1 ), 0x06, // Data, Variable, Relative
setcom_001 12:a9671b78d24e 209
setcom_001 12:a9671b78d24e 210 USAGE_PAGE( 1 ), 0x09, // Buttons
setcom_001 12:a9671b78d24e 211 USAGE_MINIMUM( 1 ), 0x01,
setcom_001 12:a9671b78d24e 212 USAGE_MAXIMUM( 1 ), 0x03,
setcom_001 12:a9671b78d24e 213 LOGICAL_MINIMUM( 1 ), 0x00, // 0
setcom_001 12:a9671b78d24e 214 LOGICAL_MAXIMUM( 1 ), 0x01, // 1
setcom_001 12:a9671b78d24e 215 REPORT_COUNT( 1 ), 0x03,
setcom_001 12:a9671b78d24e 216 REPORT_SIZE( 1 ), 0x01,
setcom_001 12:a9671b78d24e 217 INPUT( 1 ), 0x02, // Data, Variable, Absolute
setcom_001 12:a9671b78d24e 218 REPORT_COUNT( 1 ), 0x01,
setcom_001 12:a9671b78d24e 219 REPORT_SIZE( 1 ), 0x05,
setcom_001 12:a9671b78d24e 220 INPUT( 1 ), 0x01, // Constant
setcom_001 12:a9671b78d24e 221
setcom_001 12:a9671b78d24e 222 END_COLLECTION( 0 ),
setcom_001 12:a9671b78d24e 223 END_COLLECTION( 0 )
setcom_001 12:a9671b78d24e 224 };
setcom_001 12:a9671b78d24e 225 reportLength = sizeof( reportDescriptor );
setcom_001 12:a9671b78d24e 226 return reportDescriptor;
setcom_001 12:a9671b78d24e 227 }
setcom_001 12:a9671b78d24e 228
setcom_001 12:a9671b78d24e 229 return NULL;
setcom_001 12:a9671b78d24e 230 }
setcom_001 12:a9671b78d24e 231
setcom_001 12:a9671b78d24e 232 #define DEFAULT_CONFIGURATION (1)
setcom_001 12:a9671b78d24e 233 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
setcom_001 12:a9671b78d24e 234 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
setcom_001 12:a9671b78d24e 235 + (1 * HID_DESCRIPTOR_LENGTH) \
setcom_001 12:a9671b78d24e 236 + (2 * ENDPOINT_DESCRIPTOR_LENGTH))
setcom_001 12:a9671b78d24e 237
setcom_001 12:a9671b78d24e 238 uint8_t *USBMouse::configurationDesc()
setcom_001 12:a9671b78d24e 239 {
setcom_001 12:a9671b78d24e 240 static uint8_t configurationDescriptor[] =
setcom_001 12:a9671b78d24e 241 {
setcom_001 12:a9671b78d24e 242 CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
setcom_001 12:a9671b78d24e 243 CONFIGURATION_DESCRIPTOR, // bDescriptorType
setcom_001 12:a9671b78d24e 244 LSB( TOTAL_DESCRIPTOR_LENGTH ), // wTotalLength (LSB)
setcom_001 12:a9671b78d24e 245 MSB( TOTAL_DESCRIPTOR_LENGTH ), // wTotalLength (MSB)
setcom_001 12:a9671b78d24e 246 0x01, // bNumInterfaces
setcom_001 12:a9671b78d24e 247 DEFAULT_CONFIGURATION, // bConfigurationValue
setcom_001 12:a9671b78d24e 248 0x00, // iConfiguration
setcom_001 12:a9671b78d24e 249 C_RESERVED | C_SELF_POWERED, // bmAttributes
setcom_001 12:a9671b78d24e 250 C_POWER( 0 ), // bMaxPowerHello World from Mbed
setcom_001 12:a9671b78d24e 251
setcom_001 12:a9671b78d24e 252 INTERFACE_DESCRIPTOR_LENGTH, // bLength
setcom_001 12:a9671b78d24e 253 INTERFACE_DESCRIPTOR, // bDescriptorType
setcom_001 12:a9671b78d24e 254 0x00, // bInterfaceNumber
setcom_001 12:a9671b78d24e 255 0x00, // bAlternateSetting
setcom_001 12:a9671b78d24e 256 0x02, // bNumEndpoints
setcom_001 12:a9671b78d24e 257 HID_CLASS, // bInterfaceClass
setcom_001 12:a9671b78d24e 258 1, // bInterfaceSubClass
setcom_001 12:a9671b78d24e 259 2, // bInterfaceProtocol (mouse)
setcom_001 12:a9671b78d24e 260 0x00, // iInterface
setcom_001 12:a9671b78d24e 261
setcom_001 12:a9671b78d24e 262 HID_DESCRIPTOR_LENGTH, // bLength
setcom_001 12:a9671b78d24e 263 HID_DESCRIPTOR, // bDescriptorType
setcom_001 12:a9671b78d24e 264 LSB( HID_VERSION_1_11 ), // bcdHID (LSB)
setcom_001 12:a9671b78d24e 265 MSB( HID_VERSION_1_11 ), // bcdHID (MSB)
setcom_001 12:a9671b78d24e 266 0x00, // bCountryCode
setcom_001 12:a9671b78d24e 267 0x01, // bNumDescriptors
setcom_001 12:a9671b78d24e 268 REPORT_DESCRIPTOR, // bDescriptorType
setcom_001 12:a9671b78d24e 269 LSB( reportDescLength() ), // wDescriptorLength (LSB)
setcom_001 12:a9671b78d24e 270 MSB( reportDescLength() ), // wDescriptorLength (MSB)
setcom_001 12:a9671b78d24e 271
setcom_001 12:a9671b78d24e 272 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
setcom_001 12:a9671b78d24e 273 ENDPOINT_DESCRIPTOR, // bDescriptorType
setcom_001 12:a9671b78d24e 274 PHY_TO_DESC( EPINT_IN ), // bEndpointAddress
setcom_001 12:a9671b78d24e 275 E_INTERRUPT, // bmAttributes
setcom_001 12:a9671b78d24e 276 LSB( MAX_PACKET_SIZE_EPINT ), // wMaxPacketSize (LSB)
setcom_001 12:a9671b78d24e 277 MSB( MAX_PACKET_SIZE_EPINT ), // wMaxPacketSize (MSB)
setcom_001 12:a9671b78d24e 278 1, // bInterval (milliseconds)
setcom_001 12:a9671b78d24e 279
setcom_001 12:a9671b78d24e 280 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
setcom_001 12:a9671b78d24e 281 ENDPOINT_DESCRIPTOR, // bDescriptorType
setcom_001 12:a9671b78d24e 282 PHY_TO_DESC( EPINT_OUT ), // bEndpointAddress
setcom_001 12:a9671b78d24e 283 E_INTERRUPT, // bmAttributes
setcom_001 12:a9671b78d24e 284 LSB( MAX_PACKET_SIZE_EPINT ), // wMaxPacketSize (LSB)
setcom_001 12:a9671b78d24e 285 MSB( MAX_PACKET_SIZE_EPINT ), // wMaxPacketSize (MSB)
setcom_001 12:a9671b78d24e 286 1, // bInterval (milliseconds)
setcom_001 12:a9671b78d24e 287 };
setcom_001 12:a9671b78d24e 288 return configurationDescriptor;
setcom_001 12:a9671b78d24e 289 }
setcom_001 12:a9671b78d24e 290