├── Max3421e.cpp ├── Max3421e.h ├── Max3421e_constants.h ├── README ├── Usb.cpp ├── Usb.h ├── ch9.h ├── examples ├── PS3Bluetooth │ ├── HCI.ino │ ├── HCI_Commands.ino │ ├── HID_Commands.ino │ ├── L2CAP.ino │ ├── L2CAP_Commands.ino │ ├── PS3Bluetooth.ino │ ├── ReadControllerCommands.ino │ ├── enums.h │ └── progmemConstants.h └── PS3Pair │ └── PS3Pair.ino ├── gpl-3.0.txt ├── ps3_usb.cpp └── ps3_usb.h /Max3421e.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com */ 2 | /* MAX3421E USB host controller support */ 3 | 4 | #include "Max3421e.h" 5 | // #include "Max3421e_constants.h" 6 | 7 | static byte vbusState; 8 | 9 | /* Functions */ 10 | 11 | /* Constructor */ 12 | MAX3421E::MAX3421E() 13 | { 14 | spi_init(); 15 | pinMode( MAX_INT, INPUT); 16 | pinMode( MAX_GPX, INPUT ); 17 | pinMode( MAX_SS, OUTPUT ); 18 | digitalWrite(MAX_SS,HIGH); 19 | pinMode( MAX_RESET, OUTPUT ); 20 | digitalWrite( MAX_RESET, HIGH ); //release MAX3421E from reset 21 | } 22 | 23 | byte MAX3421E::getVbusState( void ) 24 | { 25 | return( vbusState ); 26 | } 27 | /* initialization */ 28 | //void MAX3421E::init() 29 | //{ 30 | // /* setup pins */ 31 | // pinMode( MAX_INT, INPUT); 32 | // pinMode( MAX_GPX, INPUT ); 33 | // pinMode( MAX_SS, OUTPUT ); 34 | // //pinMode( BPNT_0, OUTPUT ); 35 | // //pinMode( BPNT_1, OUTPUT ); 36 | // //digitalWrite( BPNT_0, LOW ); 37 | // //digitalWrite( BPNT_1, LOW ); 38 | // Deselect_MAX3421E; 39 | // pinMode( MAX_RESET, OUTPUT ); 40 | // digitalWrite( MAX_RESET, HIGH ); //release MAX3421E from reset 41 | //} 42 | //byte MAX3421E::getVbusState( void ) 43 | //{ 44 | // return( vbusState ); 45 | //} 46 | //void MAX3421E::toggle( byte pin ) 47 | //{ 48 | // digitalWrite( pin, HIGH ); 49 | // digitalWrite( pin, LOW ); 50 | //} 51 | /* Single host register write */ 52 | void MAX3421E::regWr( byte reg, byte val) 53 | { 54 | digitalWrite(MAX_SS,LOW); 55 | SPDR = ( reg | 0x02 ); 56 | while(!( SPSR & ( 1 << SPIF ))); 57 | SPDR = val; 58 | while(!( SPSR & ( 1 << SPIF ))); 59 | digitalWrite(MAX_SS,HIGH); 60 | return; 61 | } 62 | /* multiple-byte write */ 63 | /* returns a pointer to a memory position after last written */ 64 | char * MAX3421E::bytesWr( byte reg, byte nbytes, char * data ) 65 | { 66 | digitalWrite(MAX_SS,LOW); 67 | SPDR = ( reg | 0x02 ); 68 | while( nbytes-- ) { 69 | while(!( SPSR & ( 1 << SPIF ))); //check if previous byte was sent 70 | SPDR = ( *data ); // send next data byte 71 | data++; // advance data pointer 72 | } 73 | while(!( SPSR & ( 1 << SPIF ))); 74 | digitalWrite(MAX_SS,HIGH); 75 | return( data ); 76 | } 77 | /* GPIO write. GPIO byte is split between 2 registers, so two writes are needed to write one byte */ 78 | /* GPOUT bits are in the low nibble. 0-3 in IOPINS1, 4-7 in IOPINS2 */ 79 | /* upper 4 bits of IOPINS1, IOPINS2 are read-only, so no masking is necessary */ 80 | void MAX3421E::gpioWr( byte val ) 81 | { 82 | regWr( rIOPINS1, val ); 83 | val = val >>4; 84 | regWr( rIOPINS2, val ); 85 | 86 | return; 87 | } 88 | /* Single host register read */ 89 | byte MAX3421E::regRd( byte reg ) 90 | { 91 | byte tmp; 92 | digitalWrite(MAX_SS,LOW); 93 | SPDR = reg; 94 | while(!( SPSR & ( 1 << SPIF ))); 95 | SPDR = 0; //send empty byte 96 | while(!( SPSR & ( 1 << SPIF ))); 97 | digitalWrite(MAX_SS,HIGH); 98 | return( SPDR ); 99 | } 100 | /* multiple-bytes register read */ 101 | /* returns a pointer to a memory position after last read */ 102 | char * MAX3421E::bytesRd ( byte reg, byte nbytes, char * data ) 103 | { 104 | digitalWrite(MAX_SS,LOW); 105 | SPDR = reg; 106 | while(!( SPSR & ( 1 << SPIF ))); //wait 107 | while( nbytes ) { 108 | SPDR = 0; //send empty byte 109 | nbytes--; 110 | while(!( SPSR & ( 1 << SPIF ))); 111 | *data = SPDR; 112 | data++; 113 | } 114 | digitalWrite(MAX_SS,HIGH); 115 | return( data ); 116 | } 117 | /* GPIO read. See gpioWr for explanation */ 118 | /* GPIN pins are in high nibbles of IOPINS1, IOPINS2 */ 119 | byte MAX3421E::gpioRd( void ) 120 | { 121 | byte tmpbyte = 0; 122 | tmpbyte = regRd( rIOPINS2 ); //pins 4-7 123 | tmpbyte &= 0xf0; //clean lower nibble 124 | tmpbyte |= ( regRd( rIOPINS1 ) >>4 ) ; //shift low bits and OR with upper from previous operation. Upper nibble zeroes during shift, at least with this compiler 125 | return( tmpbyte ); 126 | } 127 | /* reset MAX3421E using chip reset bit. SPI configuration is not affected */ 128 | boolean MAX3421E::reset() 129 | { 130 | byte tmp = 0; 131 | regWr( rUSBCTL, bmCHIPRES ); //Chip reset. This stops the oscillator 132 | regWr( rUSBCTL, 0x00 ); //Remove the reset 133 | while(!(regRd( rUSBIRQ ) & bmOSCOKIRQ )) { //wait until the PLL is stable 134 | tmp++; //timeout after 256 attempts 135 | if( tmp == 0 ) { 136 | return( false ); 137 | } 138 | } 139 | return( true ); 140 | } 141 | /* turn USB power on/off */ 142 | /* does nothing, returns TRUE. Left for compatibility with old sketches */ 143 | /* will be deleted eventually */ 144 | ///* ON pin of VBUS switch (MAX4793 or similar) is connected to GPOUT7 */ 145 | ///* OVERLOAD pin of Vbus switch is connected to GPIN7 */ 146 | ///* OVERLOAD state low. NO OVERLOAD or VBUS OFF state high. */ 147 | boolean MAX3421E::vbusPwr ( boolean action ) 148 | { 149 | // byte tmp; 150 | // tmp = regRd( rIOPINS2 ); //copy of IOPINS2 151 | // if( action ) { //turn on by setting GPOUT7 152 | // tmp |= bmGPOUT7; 153 | // } 154 | // else { //turn off by clearing GPOUT7 155 | // tmp &= ~bmGPOUT7; 156 | // } 157 | // regWr( rIOPINS2, tmp ); //send GPOUT7 158 | // if( action ) { 159 | // delay( 60 ); 160 | // } 161 | // if (( regRd( rIOPINS2 ) & bmGPIN7 ) == 0 ) { // check if overload is present. MAX4793 /FLAG ( pin 4 ) goes low if overload 162 | // return( false ); 163 | // } 164 | return( true ); // power on/off successful 165 | } 166 | /* probe bus to determine device presense and speed and switch host to this speed */ 167 | void MAX3421E::busprobe( void ) 168 | { 169 | byte bus_sample; 170 | bus_sample = regRd( rHRSL ); //Get J,K status 171 | bus_sample &= ( bmJSTATUS|bmKSTATUS ); //zero the rest of the byte 172 | switch( bus_sample ) { //start full-speed or low-speed host 173 | case( bmJSTATUS ): 174 | if(( regRd( rMODE ) & bmLOWSPEED ) == 0 ) { 175 | regWr( rMODE, MODE_FS_HOST ); //start full-speed host 176 | vbusState = FSHOST; 177 | } 178 | else { 179 | regWr( rMODE, MODE_LS_HOST); //start low-speed host 180 | vbusState = LSHOST; 181 | } 182 | break; 183 | case( bmKSTATUS ): 184 | if(( regRd( rMODE ) & bmLOWSPEED ) == 0 ) { 185 | regWr( rMODE, MODE_LS_HOST ); //start low-speed host 186 | vbusState = LSHOST; 187 | } 188 | else { 189 | regWr( rMODE, MODE_FS_HOST ); //start full-speed host 190 | vbusState = FSHOST; 191 | } 192 | break; 193 | case( bmSE1 ): //illegal state 194 | vbusState = SE1; 195 | break; 196 | case( bmSE0 ): //disconnected state 197 | regWr( rMODE, bmDPPULLDN|bmDMPULLDN|bmHOST|bmSEPIRQ); 198 | vbusState = SE0; 199 | break; 200 | }//end switch( bus_sample ) 201 | } 202 | /* MAX3421E initialization after power-on */ 203 | void MAX3421E::powerOn() 204 | { 205 | /* Configure full-duplex SPI, interrupt pulse */ 206 | regWr( rPINCTL,( bmFDUPSPI + bmINTLEVEL + bmGPXB )); //Full-duplex SPI, level interrupt, GPX 207 | if( reset() == false ) { //stop/start the oscillator 208 | Serial.println("Error: OSCOKIRQ failed to assert"); 209 | } 210 | 211 | /* configure host operation */ 212 | regWr( rMODE, bmDPPULLDN|bmDMPULLDN|bmHOST|bmSEPIRQ ); // set pull-downs, Host, Separate GPIN IRQ on GPX 213 | regWr( rHIEN, bmCONDETIE|bmFRAMEIE ); //connection detection 214 | /* check if device is connected */ 215 | regWr( rHCTL,bmSAMPLEBUS ); // sample USB bus 216 | while(!(regRd( rHCTL ) & bmSAMPLEBUS )); //wait for sample operation to finish 217 | busprobe(); //check if anything is connected 218 | regWr( rHIRQ, bmCONDETIRQ ); //clear connection detect interrupt 219 | regWr( rCPUCTL, 0x01 ); //enable interrupt pin 220 | } 221 | /* MAX3421 state change task and interrupt handler */ 222 | byte MAX3421E::Task( void ) 223 | { 224 | byte rcode = 0; 225 | byte pinvalue; 226 | //Serial.print("Vbus state: "); 227 | //Serial.println( vbusState, HEX ); 228 | pinvalue = digitalRead( MAX_INT ); 229 | if( pinvalue == LOW ) { 230 | rcode = IntHandler(); 231 | } 232 | pinvalue = digitalRead( MAX_GPX ); 233 | if( pinvalue == LOW ) { 234 | GpxHandler(); 235 | } 236 | // usbSM(); //USB state machine 237 | return( rcode ); 238 | } 239 | byte MAX3421E::IntHandler() 240 | { 241 | byte HIRQ; 242 | byte HIRQ_sendback = 0x00; 243 | HIRQ = regRd( rHIRQ ); //determine interrupt source 244 | //if( HIRQ & bmFRAMEIRQ ) { //->1ms SOF interrupt handler 245 | // HIRQ_sendback |= bmFRAMEIRQ; 246 | //}//end FRAMEIRQ handling 247 | if( HIRQ & bmCONDETIRQ ) { 248 | busprobe(); 249 | HIRQ_sendback |= bmCONDETIRQ; 250 | } 251 | /* End HIRQ interrupts handling, clear serviced IRQs */ 252 | regWr( rHIRQ, HIRQ_sendback ); 253 | return( HIRQ_sendback ); 254 | } 255 | byte MAX3421E::GpxHandler() 256 | { 257 | byte GPINIRQ = regRd( rGPINIRQ ); //read GPIN IRQ register 258 | // if( GPINIRQ & bmGPINIRQ7 ) { //vbus overload 259 | // vbusPwr( OFF ); //attempt powercycle 260 | // delay( 1000 ); 261 | // vbusPwr( ON ); 262 | // regWr( rGPINIRQ, bmGPINIRQ7 ); 263 | // } 264 | return( GPINIRQ ); 265 | } 266 | 267 | //void MAX3421E::usbSM( void ) //USB state machine 268 | //{ 269 | // 270 | // 271 | //} 272 | -------------------------------------------------------------------------------- /Max3421e.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com */ 2 | /* MAX3421E functions */ 3 | #ifndef _MAX3421E_H_ 4 | #define _MAX3421E_H_ 5 | 6 | 7 | //#include 8 | //#include 9 | 10 | #if defined(ARDUINO) && ARDUINO >= 100 11 | #include "Arduino.h" 12 | #else 13 | #include "WProgram.h" 14 | #endif 15 | 16 | #include "Max3421e_constants.h" 17 | 18 | class MAX3421E /* : public SPI */ { 19 | // byte vbusState; 20 | public: 21 | MAX3421E( void ); 22 | uint8_t getVbusState( void ); 23 | // void toggle( byte pin ); 24 | static void regWr( byte, byte ); 25 | char * bytesWr( byte, byte, char * ); 26 | static void gpioWr( byte ); 27 | uint8_t regRd( byte ); 28 | char * bytesRd( byte, byte, char * ); 29 | uint8_t gpioRd( void ); 30 | boolean reset(); 31 | boolean vbusPwr ( boolean ); 32 | void busprobe( void ); 33 | void powerOn(); 34 | uint8_t IntHandler(); 35 | uint8_t GpxHandler(); 36 | uint8_t Task(); 37 | private: 38 | static void spi_init() { 39 | uint8_t tmp; 40 | // initialize SPI pins 41 | pinMode(SCK_PIN, OUTPUT); 42 | pinMode(MOSI_PIN, OUTPUT); 43 | pinMode(MISO_PIN, INPUT); 44 | pinMode(SS_PIN, OUTPUT); 45 | digitalWrite( SS_PIN, HIGH ); 46 | /* mode 00 (CPOL=0, CPHA=0) master, fclk/2. Mode 11 (CPOL=11, CPHA=11) is also supported by MAX3421E */ 47 | SPCR = 0x50; 48 | SPSR = 0x01; 49 | /**/ 50 | tmp = SPSR; 51 | tmp = SPDR; 52 | } 53 | // void init(); 54 | friend class Max_LCD; 55 | }; 56 | 57 | 58 | 59 | 60 | #endif //_MAX3421E_H_ 61 | -------------------------------------------------------------------------------- /Max3421e_constants.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com */ 2 | /* MAX3421E register/bit names and bitmasks */ 3 | 4 | #ifndef _MAX3421Econstants_h_ 5 | #define _MAX3421Econstants_h_ 6 | 7 | /* SPI pins for diffrent Arduinos */ 8 | 9 | #if defined(__AVR_ATmega1280__) || (__AVR_ATmega2560__) 10 | #define SCK_PIN 52 11 | #define MISO_PIN 50 12 | #define MOSI_PIN 51 13 | #define SS_PIN 53 14 | #endif 15 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) 16 | #define SCK_PIN 13 17 | #define MISO_PIN 12 18 | #define MOSI_PIN 11 19 | #define SS_PIN 10 20 | #endif 21 | 22 | #define MAX_SS 10 23 | #define MAX_INT 9 24 | #define MAX_GPX 8 25 | #define MAX_RESET 7 26 | 27 | /* "Breakpoint" pins for debugging */ 28 | //#define BPNT_0 3 29 | //#define BPNT_1 2 30 | 31 | //#define Select_MAX3421E digitalWrite(MAX_SS,LOW) 32 | //#define Deselect_MAX3421E digitalWrite(MAX_SS,HIGH) 33 | 34 | /* */ 35 | 36 | #define ON true 37 | #define OFF false 38 | 39 | /* VBUS states */ 40 | #define SE0 0 41 | #define SE1 1 42 | #define FSHOST 2 43 | #define LSHOST 3 44 | 45 | /* MAX3421E command byte format: rrrrr0wa where 'r' is register number */ 46 | // 47 | // MAX3421E Registers in HOST mode. 48 | // 49 | #define rRCVFIFO 0x08 //1<<3 50 | #define rSNDFIFO 0x10 //2<<3 51 | #define rSUDFIFO 0x20 //4<<3 52 | #define rRCVBC 0x30 //6<<3 53 | #define rSNDBC 0x38 //7<<3 54 | 55 | #define rUSBIRQ 0x68 //13<<3 56 | /* USBIRQ Bits */ 57 | #define bmVBUSIRQ 0x40 //b6 58 | #define bmNOVBUSIRQ 0x20 //b5 59 | #define bmOSCOKIRQ 0x01 //b0 60 | 61 | #define rUSBIEN 0x70 //14<<3 62 | /* USBIEN Bits */ 63 | #define bmVBUSIE 0x40 //b6 64 | #define bmNOVBUSIE 0x20 //b5 65 | #define bmOSCOKIE 0x01 //b0 66 | 67 | #define rUSBCTL 0x78 //15<<3 68 | /* USBCTL Bits */ 69 | #define bmCHIPRES 0x20 //b5 70 | #define bmPWRDOWN 0x10 //b4 71 | 72 | #define rCPUCTL 0x80 //16<<3 73 | /* CPUCTL Bits */ 74 | #define bmPUSLEWID1 0x80 //b7 75 | #define bmPULSEWID0 0x40 //b6 76 | #define bmIE 0x01 //b0 77 | 78 | #define rPINCTL 0x88 //17<<3 79 | /* PINCTL Bits */ 80 | #define bmFDUPSPI 0x10 //b4 81 | #define bmINTLEVEL 0x08 //b3 82 | #define bmPOSINT 0x04 //b2 83 | #define bmGPXB 0x02 //b1 84 | #define bmGPXA 0x01 //b0 85 | // GPX pin selections 86 | #define GPX_OPERATE 0x00 87 | #define GPX_VBDET 0x01 88 | #define GPX_BUSACT 0x02 89 | #define GPX_SOF 0x03 90 | 91 | #define rREVISION 0x90 //18<<3 92 | 93 | #define rIOPINS1 0xa0 //20<<3 94 | 95 | /* IOPINS1 Bits */ 96 | #define bmGPOUT0 0x01 97 | #define bmGPOUT1 0x02 98 | #define bmGPOUT2 0x04 99 | #define bmGPOUT3 0x08 100 | #define bmGPIN0 0x10 101 | #define bmGPIN1 0x20 102 | #define bmGPIN2 0x40 103 | #define bmGPIN3 0x80 104 | 105 | #define rIOPINS2 0xa8 //21<<3 106 | /* IOPINS2 Bits */ 107 | #define bmGPOUT4 0x01 108 | #define bmGPOUT5 0x02 109 | #define bmGPOUT6 0x04 110 | #define bmGPOUT7 0x08 111 | #define bmGPIN4 0x10 112 | #define bmGPIN5 0x20 113 | #define bmGPIN6 0x40 114 | #define bmGPIN7 0x80 115 | 116 | #define rGPINIRQ 0xb0 //22<<3 117 | /* GPINIRQ Bits */ 118 | #define bmGPINIRQ0 0x01 119 | #define bmGPINIRQ1 0x02 120 | #define bmGPINIRQ2 0x04 121 | #define bmGPINIRQ3 0x08 122 | #define bmGPINIRQ4 0x10 123 | #define bmGPINIRQ5 0x20 124 | #define bmGPINIRQ6 0x40 125 | #define bmGPINIRQ7 0x80 126 | 127 | #define rGPINIEN 0xb8 //23<<3 128 | /* GPINIEN Bits */ 129 | #define bmGPINIEN0 0x01 130 | #define bmGPINIEN1 0x02 131 | #define bmGPINIEN2 0x04 132 | #define bmGPINIEN3 0x08 133 | #define bmGPINIEN4 0x10 134 | #define bmGPINIEN5 0x20 135 | #define bmGPINIEN6 0x40 136 | #define bmGPINIEN7 0x80 137 | 138 | #define rGPINPOL 0xc0 //24<<3 139 | /* GPINPOL Bits */ 140 | #define bmGPINPOL0 0x01 141 | #define bmGPINPOL1 0x02 142 | #define bmGPINPOL2 0x04 143 | #define bmGPINPOL3 0x08 144 | #define bmGPINPOL4 0x10 145 | #define bmGPINPOL5 0x20 146 | #define bmGPINPOL6 0x40 147 | #define bmGPINPOL7 0x80 148 | 149 | #define rHIRQ 0xc8 //25<<3 150 | /* HIRQ Bits */ 151 | #define bmBUSEVENTIRQ 0x01 // indicates BUS Reset Done or BUS Resume 152 | #define bmRWUIRQ 0x02 153 | #define bmRCVDAVIRQ 0x04 154 | #define bmSNDBAVIRQ 0x08 155 | #define bmSUSDNIRQ 0x10 156 | #define bmCONDETIRQ 0x20 157 | #define bmFRAMEIRQ 0x40 158 | #define bmHXFRDNIRQ 0x80 159 | 160 | #define rHIEN 0xd0 //26<<3 161 | /* HIEN Bits */ 162 | #define bmBUSEVENTIE 0x01 163 | #define bmRWUIE 0x02 164 | #define bmRCVDAVIE 0x04 165 | #define bmSNDBAVIE 0x08 166 | #define bmSUSDNIE 0x10 167 | #define bmCONDETIE 0x20 168 | #define bmFRAMEIE 0x40 169 | #define bmHXFRDNIE 0x80 170 | 171 | #define rMODE 0xd8 //27<<3 172 | /* MODE Bits */ 173 | #define bmHOST 0x01 174 | #define bmLOWSPEED 0x02 175 | #define bmHUBPRE 0x04 176 | #define bmSOFKAENAB 0x08 177 | #define bmSEPIRQ 0x10 178 | #define bmDELAYISO 0x20 179 | #define bmDMPULLDN 0x40 180 | #define bmDPPULLDN 0x80 181 | 182 | #define rPERADDR 0xe0 //28<<3 183 | 184 | #define rHCTL 0xe8 //29<<3 185 | /* HCTL Bits */ 186 | #define bmBUSRST 0x01 187 | #define bmFRMRST 0x02 188 | #define bmSAMPLEBUS 0x04 189 | #define bmSIGRSM 0x08 190 | #define bmRCVTOG0 0x10 191 | #define bmRCVTOG1 0x20 192 | #define bmSNDTOG0 0x40 193 | #define bmSNDTOG1 0x80 194 | 195 | #define rHXFR 0xf0 //30<<3 196 | /* Host transfer token values for writing the HXFR register (R30) */ 197 | /* OR this bit field with the endpoint number in bits 3:0 */ 198 | #define tokSETUP 0x10 // HS=0, ISO=0, OUTNIN=0, SETUP=1 199 | #define tokIN 0x00 // HS=0, ISO=0, OUTNIN=0, SETUP=0 200 | #define tokOUT 0x20 // HS=0, ISO=0, OUTNIN=1, SETUP=0 201 | #define tokINHS 0x80 // HS=1, ISO=0, OUTNIN=0, SETUP=0 202 | #define tokOUTHS 0xA0 // HS=1, ISO=0, OUTNIN=1, SETUP=0 203 | #define tokISOIN 0x40 // HS=0, ISO=1, OUTNIN=0, SETUP=0 204 | #define tokISOOUT 0x60 // HS=0, ISO=1, OUTNIN=1, SETUP=0 205 | 206 | #define rHRSL 0xf8 //31<<3 207 | /* HRSL Bits */ 208 | #define bmRCVTOGRD 0x10 209 | #define bmSNDTOGRD 0x20 210 | #define bmKSTATUS 0x40 211 | #define bmJSTATUS 0x80 212 | #define bmSE0 0x00 //SE0 - disconnect state 213 | #define bmSE1 0xc0 //SE1 - illegal state 214 | /* Host error result codes, the 4 LSB's in the HRSL register */ 215 | #define hrSUCCESS 0x00 216 | #define hrBUSY 0x01 217 | #define hrBADREQ 0x02 218 | #define hrUNDEF 0x03 219 | #define hrNAK 0x04 220 | #define hrSTALL 0x05 221 | #define hrTOGERR 0x06 222 | #define hrWRONGPID 0x07 223 | #define hrBADBC 0x08 224 | #define hrPIDERR 0x09 225 | #define hrPKTERR 0x0A 226 | #define hrCRCERR 0x0B 227 | #define hrKERR 0x0C 228 | #define hrJERR 0x0D 229 | #define hrTIMEOUT 0x0E 230 | #define hrBABBLE 0x0F 231 | 232 | #define MODE_FS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmSOFKAENAB) 233 | #define MODE_LS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmLOWSPEED|bmSOFKAENAB) 234 | 235 | 236 | #endif //_MAX3421Econstants_h_ 237 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | NB: This is the old version of the library, the newest version can be found at the following link: https://github.com/TKJElectronics/USB_Host_Shield_2.0 2 | 3 | The code is released under the GNU General Public License. 4 | This code was developed by Kristian Lauszus. 5 | 6 | For more information visit his blog at: http://blog.tkjelectronics.dk/ or send him an email at kristianl at tkjelectronics dot dk. 7 | You should also visit the official wiki: https://github.com/Lauszus/PS3-Controller-BT-Library-for-Arduino/wiki/PS3-Controller-BT-wiki for information. 8 | 9 | All three PS3 Controllers are supported (Dualshock 3-, Navigation-, and Motioncontroller). 10 | They communicate with the Arduino via Bluetooth using the USB Host Shield from http://www.circuitsathome.com/ 11 | 12 | A special thanks go to the following people: 13 | "Richard Ibbotson" who made this guide: http://www.circuitsathome.com/mcu/ps3-and-wiimote-game-controllers-on-the-arduino-host-shield-part-1 14 | - It inspired me to get starting and had a lot of good information for the USB communication 15 | 16 | "Tomoyuki Tanaka" for releasing his code for the Arduino USB Host shield connected to the wiimote: http://www.circuitsathome.com/mcu/rc-car-controlled-by-wii-remote-on-arduino 17 | - It helped me a lot to see the structure of the bluetooth communication 18 | 19 | Also I would like to thank all the people behind these sites about the Motion controller: 20 | http://thp.io/2010/psmove/ 21 | http://www.copenhagengamecollective.org/unimove/ 22 | https://github.com/thp/psmoveapi 23 | http://code.google.com/p/moveonpc/ 24 | 25 | And at last I would like to thank Oleg from http://www.circuitsathome.com/ for making such an awesome shield! -------------------------------------------------------------------------------- /Usb.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com */ 2 | /* USB functions */ 3 | 4 | #include "Usb.h" 5 | 6 | static byte usb_error = 0; 7 | static byte usb_task_state; 8 | DEV_RECORD devtable[ USB_NUMDEVICES + 1 ]; 9 | EP_RECORD dev0ep; //Endpoint data structure used during enumeration for uninitialized device 10 | 11 | 12 | /* constructor */ 13 | 14 | USB::USB () { 15 | usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; //set up state machine 16 | init(); 17 | } 18 | /* Initialize data structures */ 19 | void USB::init() 20 | { 21 | byte i; 22 | for( i = 0; i < ( USB_NUMDEVICES + 1 ); i++ ) { 23 | devtable[ i ].epinfo = NULL; //clear device table 24 | devtable[ i ].devclass = 0; 25 | } 26 | devtable[ 0 ].epinfo = &dev0ep; //set single ep for uninitialized device 27 | // not necessary dev0ep.MaxPktSize = 8; //minimum possible 28 | dev0ep.sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0 29 | dev0ep.rcvToggle = bmRCVTOG0; 30 | } 31 | byte USB::getUsbTaskState( void ) 32 | { 33 | return( usb_task_state ); 34 | } 35 | void USB::setUsbTaskState( byte state ) 36 | { 37 | usb_task_state = state; 38 | } 39 | EP_RECORD* USB::getDevTableEntry( byte addr, byte ep ) 40 | { 41 | EP_RECORD* ptr; 42 | ptr = devtable[ addr ].epinfo; 43 | ptr += ep; 44 | return( ptr ); 45 | } 46 | /* set device table entry */ 47 | /* each device is different and has different number of endpoints. This function plugs endpoint record structure, defined in application, to devtable */ 48 | void USB::setDevTableEntry( byte addr, EP_RECORD* eprecord_ptr ) 49 | { 50 | devtable[ addr ].epinfo = eprecord_ptr; 51 | //return(); 52 | } 53 | /* Control transfer. Sets address, endpoint, fills control packet with necessary data, dispatches control packet, and initiates bulk IN transfer, */ 54 | /* depending on request. Actual requests are defined as inlines */ 55 | /* return codes: */ 56 | /* 00 = success */ 57 | /* 01-0f = non-zero HRSLT */ 58 | byte USB::ctrlReq( byte addr, byte ep, byte bmReqType, byte bRequest, byte wValLo, byte wValHi, unsigned int wInd, unsigned int nbytes, char* dataptr, unsigned int nak_limit ) 59 | { 60 | boolean direction = false; //request direction, IN or OUT 61 | byte rcode; 62 | SETUP_PKT setup_pkt; 63 | 64 | regWr( rPERADDR, addr ); //set peripheral address 65 | if( bmReqType & 0x80 ) { 66 | direction = true; //determine request direction 67 | } 68 | /* fill in setup packet */ 69 | setup_pkt.ReqType_u.bmRequestType = bmReqType; 70 | setup_pkt.bRequest = bRequest; 71 | setup_pkt.wVal_u.wValueLo = wValLo; 72 | setup_pkt.wVal_u.wValueHi = wValHi; 73 | setup_pkt.wIndex = wInd; 74 | setup_pkt.wLength = nbytes; 75 | bytesWr( rSUDFIFO, 8, ( char *)&setup_pkt ); //transfer to setup packet FIFO 76 | rcode = dispatchPkt( tokSETUP, ep, nak_limit ); //dispatch packet 77 | //Serial.println("Setup packet"); //DEBUG 78 | if( rcode ) { //return HRSLT if not zero 79 | Serial.print("Setup packet error: "); 80 | Serial.print( rcode, HEX ); 81 | return( rcode ); 82 | } 83 | //Serial.println( direction, HEX ); 84 | if( dataptr != NULL ) { //data stage, if present 85 | rcode = ctrlData( addr, ep, nbytes, dataptr, direction ); 86 | } 87 | if( rcode ) { //return error 88 | Serial.print("Data packet error: "); 89 | Serial.print( rcode, HEX ); 90 | return( rcode ); 91 | } 92 | rcode = ctrlStatus( ep, direction ); //status stage 93 | return( rcode ); 94 | } 95 | /* Control transfer with status stage and no data stage */ 96 | /* Assumed peripheral address is already set */ 97 | byte USB::ctrlStatus( byte ep, boolean direction, unsigned int nak_limit ) 98 | { 99 | byte rcode; 100 | if( direction ) { //GET 101 | rcode = dispatchPkt( tokOUTHS, ep, nak_limit ); 102 | } 103 | else { 104 | rcode = dispatchPkt( tokINHS, ep, nak_limit ); 105 | } 106 | return( rcode ); 107 | } 108 | /* Control transfer with data stage. Stages 2 and 3 of control transfer. Assumes preipheral address is set and setup packet has been sent */ 109 | byte USB::ctrlData( byte addr, byte ep, unsigned int nbytes, char* dataptr, boolean direction, unsigned int nak_limit ) 110 | { 111 | byte rcode; 112 | if( direction ) { //IN transfer 113 | devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG1; 114 | rcode = inTransfer( addr, ep, nbytes, dataptr, nak_limit ); 115 | return( rcode ); 116 | } 117 | else { //OUT transfer 118 | devtable[ addr ].epinfo[ ep ].sndToggle = bmSNDTOG1; 119 | rcode = outTransfer( addr, ep, nbytes, dataptr, nak_limit ); 120 | return( rcode ); 121 | } 122 | } 123 | /* IN transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */ 124 | /* Keep sending INs and writes data to memory area pointed by 'data' */ 125 | /* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error, 126 | fe USB xfer timeout */ 127 | byte USB::inTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit ) 128 | { 129 | byte rcode; 130 | byte pktsize; 131 | byte maxpktsize = devtable[ addr ].epinfo[ ep ].MaxPktSize; 132 | unsigned int xfrlen = 0; 133 | regWr( rHCTL, devtable[ addr ].epinfo[ ep ].rcvToggle ); //set toggle value 134 | while( 1 ) { // use a 'return' to exit this loop 135 | rcode = dispatchPkt( tokIN, ep, nak_limit ); //IN packet to EP-'endpoint'. Function takes care of NAKS. 136 | if( rcode ) { 137 | return( rcode ); //should be 0, indicating ACK. Else return error code. 138 | } 139 | /* check for RCVDAVIRQ and generate error if not present */ 140 | /* the only case when absense of RCVDAVIRQ makes sense is when toggle error occured. Need to add handling for that */ 141 | if(( regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 ) { 142 | return ( 0xf0 ); //receive error 143 | } 144 | pktsize = regRd( rRCVBC ); //number of received bytes 145 | data = bytesRd( rRCVFIFO, pktsize, data ); 146 | regWr( rHIRQ, bmRCVDAVIRQ ); // Clear the IRQ & free the buffer 147 | xfrlen += pktsize; // add this packet's byte count to total transfer length 148 | /* The transfer is complete under two conditions: */ 149 | /* 1. The device sent a short packet (L.T. maxPacketSize) */ 150 | /* 2. 'nbytes' have been transferred. */ 151 | if (( pktsize < maxpktsize ) || (xfrlen >= nbytes )) { // have we transferred 'nbytes' bytes? 152 | if( regRd( rHRSL ) & bmRCVTOGRD ) { //save toggle value 153 | devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG1; 154 | } 155 | else { 156 | devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG0; 157 | } 158 | return( 0 ); 159 | } 160 | }//while( 1 ) 161 | } 162 | 163 | /* Google variant of inTransfer. Pasted verbatim from ADK. Returns length instead of error code. Provided for compatibility with Google Open Accessory code */ 164 | int USB::newInTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit ) 165 | { 166 | byte rcode; 167 | byte pktsize; 168 | byte maxpktsize = devtable[ addr ].epinfo[ ep ].MaxPktSize; 169 | unsigned int xfrlen = 0; 170 | regWr( rHCTL, devtable[ addr ].epinfo[ ep ].rcvToggle ); //set toggle value 171 | while( 1 ) { // use a 'return' to exit this loop 172 | rcode = dispatchPkt( tokIN, ep, nak_limit ); //IN packet to EP-'endpoint'. Function takes care of NAKS. 173 | if( rcode ) { 174 | return -1; //should be 0, indicating ACK. Else return error code. 175 | } 176 | /* check for RCVDAVIRQ and generate error if not present */ 177 | /* the only case when absense of RCVDAVIRQ makes sense is when toggle error occured. Need to add handling for that */ 178 | if(( regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 ) { 179 | return -1; //receive error 180 | } 181 | pktsize = regRd( rRCVBC ); //number of received bytes 182 | data = bytesRd( rRCVFIFO, pktsize, data ); 183 | regWr( rHIRQ, bmRCVDAVIRQ ); // Clear the IRQ & free the buffer 184 | xfrlen += pktsize; // add this packet's byte count to total transfer length 185 | /* The transfer is complete under two conditions: */ 186 | /* 1. The device sent a short packet (L.T. maxPacketSize) */ 187 | /* 2. 'nbytes' have been transferred. */ 188 | if (( pktsize < maxpktsize ) || (xfrlen >= nbytes )) { // have we transferred 'nbytes' bytes? 189 | if( regRd( rHRSL ) & bmRCVTOGRD ) { //save toggle value 190 | devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG1; 191 | } 192 | else { 193 | devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG0; 194 | } 195 | return xfrlen; 196 | } 197 | }//while( 1 ) 198 | } 199 | 200 | /* OUT transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */ 201 | /* Handles NAK bug per Maxim Application Note 4000 for single buffer transfer */ 202 | /* rcode 0 if no errors. rcode 01-0f is relayed from HRSL */ 203 | /* major part of this function borrowed from code shared by Richard Ibbotson */ 204 | byte USB::outTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit ) 205 | { 206 | byte rcode, retry_count; 207 | char* data_p = data; //local copy of the data pointer 208 | unsigned int bytes_tosend, nak_count; 209 | unsigned int bytes_left = nbytes; 210 | byte maxpktsize = devtable[ addr ].epinfo[ ep ].MaxPktSize; 211 | unsigned long timeout = millis() + USB_XFER_TIMEOUT; 212 | 213 | if (!maxpktsize) { //todo: move this check close to epinfo init. Make it 1< pktsize <64 214 | return 0xFE; 215 | } 216 | 217 | regWr( rHCTL, devtable[ addr ].epinfo[ ep ].sndToggle ); //set toggle value 218 | while( bytes_left ) { 219 | retry_count = 0; 220 | nak_count = 0; 221 | bytes_tosend = ( bytes_left >= maxpktsize ) ? maxpktsize : bytes_left; 222 | bytesWr( rSNDFIFO, bytes_tosend, data_p ); //filling output FIFO 223 | regWr( rSNDBC, bytes_tosend ); //set number of bytes 224 | regWr( rHXFR, ( tokOUT | ep )); //dispatch packet 225 | while(!(regRd( rHIRQ ) & bmHXFRDNIRQ )); //wait for the completion IRQ 226 | regWr( rHIRQ, bmHXFRDNIRQ ); //clear IRQ 227 | rcode = ( regRd( rHRSL ) & 0x0f ); 228 | while( rcode && ( timeout > millis())) { 229 | switch( rcode ) { 230 | case hrNAK: 231 | nak_count++; 232 | if( nak_limit && ( nak_count == USB_NAK_LIMIT )) { 233 | return( rcode); //return NAK 234 | } 235 | break; 236 | case hrTIMEOUT: 237 | retry_count++; 238 | if( retry_count == USB_RETRY_LIMIT ) { 239 | return( rcode ); //return TIMEOUT 240 | } 241 | break; 242 | default: 243 | return( rcode ); 244 | }//switch( rcode... 245 | /* process NAK according to Host out NAK bug */ 246 | regWr( rSNDBC, 0 ); 247 | regWr( rSNDFIFO, *data_p ); 248 | regWr( rSNDBC, bytes_tosend ); 249 | regWr( rHXFR, ( tokOUT | ep )); //dispatch packet 250 | while(!(regRd( rHIRQ ) & bmHXFRDNIRQ )); //wait for the completion IRQ 251 | regWr( rHIRQ, bmHXFRDNIRQ ); //clear IRQ 252 | rcode = ( regRd( rHRSL ) & 0x0f ); 253 | }//while( rcode && .... 254 | bytes_left -= bytes_tosend; 255 | data_p += bytes_tosend; 256 | }//while( bytes_left... 257 | devtable[ addr ].epinfo[ ep ].sndToggle = ( regRd( rHRSL ) & bmSNDTOGRD ) ? bmSNDTOG1 : bmSNDTOG0; //update toggle 258 | return( rcode ); //should be 0 in all cases 259 | } 260 | /* dispatch usb packet. Assumes peripheral address is set and relevant buffer is loaded/empty */ 261 | /* If NAK, tries to re-send up to nak_limit times */ 262 | /* If nak_limit == 0, do not count NAKs, exit after timeout */ 263 | /* If bus timeout, re-sends up to USB_RETRY_LIMIT times */ 264 | /* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout */ 265 | byte USB::dispatchPkt( byte token, byte ep, unsigned int nak_limit ) 266 | { 267 | unsigned long timeout = millis() + USB_XFER_TIMEOUT; 268 | byte tmpdata; 269 | byte rcode; 270 | unsigned int nak_count = 0; 271 | char retry_count = 0; 272 | 273 | while( timeout > millis() ) { 274 | regWr( rHXFR, ( token|ep )); //launch the transfer 275 | rcode = 0xff; 276 | while( millis() < timeout ) { //wait for transfer completion 277 | tmpdata = regRd( rHIRQ ); 278 | if( tmpdata & bmHXFRDNIRQ ) { 279 | regWr( rHIRQ, bmHXFRDNIRQ ); //clear the interrupt 280 | rcode = 0x00; 281 | break; 282 | }//if( tmpdata & bmHXFRDNIRQ 283 | }//while ( millis() < timeout 284 | if( rcode != 0x00 ) { //exit if timeout 285 | return( rcode ); 286 | } 287 | rcode = ( regRd( rHRSL ) & 0x0f ); //analyze transfer result 288 | switch( rcode ) { 289 | case hrNAK: 290 | nak_count ++; 291 | if( nak_limit && ( nak_count == nak_limit )) { 292 | return( rcode ); 293 | } 294 | break; 295 | case hrTIMEOUT: 296 | retry_count ++; 297 | if( retry_count == USB_RETRY_LIMIT ) { 298 | return( rcode ); 299 | } 300 | break; 301 | default: 302 | return( rcode ); 303 | }//switch( rcode 304 | }//while( timeout > millis() 305 | return( rcode ); 306 | } 307 | /* USB main task. Performs enumeration/cleanup */ 308 | void USB::Task( void ) //USB state machine 309 | { 310 | byte i; 311 | byte rcode; 312 | static byte tmpaddr; 313 | byte tmpdata; 314 | static unsigned long delay = 0; 315 | USB_DEVICE_DESCRIPTOR buf; 316 | /**/ 317 | tmpdata = getVbusState(); 318 | // Serial.print("vbusState: "); 319 | // Serial.print(tmpdata, HEX); 320 | // 321 | // Serial.print("\n"); 322 | /**/ 323 | /* modify USB task state if Vbus changed */ 324 | 325 | switch( tmpdata ) { 326 | case SE1: //illegal state 327 | usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL; 328 | break; 329 | case SE0: //disconnected 330 | if(( usb_task_state & USB_STATE_MASK ) != USB_STATE_DETACHED ) { 331 | usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; 332 | } 333 | break; 334 | case FSHOST: //attached 335 | case LSHOST: 336 | if(( usb_task_state & USB_STATE_MASK ) == USB_STATE_DETACHED ) { 337 | delay = millis() + USB_SETTLE_DELAY; 338 | usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE; 339 | } 340 | break; 341 | }// switch( tmpdata 342 | //Serial.print("USB task state: "); 343 | //Serial.println( usb_task_state, HEX ); 344 | switch( usb_task_state ) { 345 | case USB_DETACHED_SUBSTATE_INITIALIZE: 346 | init(); 347 | usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE; 348 | break; 349 | case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here 350 | break; 351 | case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here 352 | break; 353 | case USB_ATTACHED_SUBSTATE_SETTLE: //setlle time for just attached device 354 | if( delay < millis() ) { 355 | usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE; 356 | } 357 | break; 358 | case USB_ATTACHED_SUBSTATE_RESET_DEVICE: 359 | regWr( rHCTL, bmBUSRST ); //issue bus reset 360 | usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE; 361 | break; 362 | case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE: 363 | if(( regRd( rHCTL ) & bmBUSRST ) == 0 ) { 364 | tmpdata = regRd( rMODE ) | bmSOFKAENAB; //start SOF generation 365 | regWr( rMODE, tmpdata ); 366 | // regWr( rMODE, bmSOFKAENAB ); 367 | usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF; 368 | delay = millis() + 20; //20ms wait after reset per USB spec 369 | } 370 | break; 371 | case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order 372 | if( regRd( rHIRQ ) & bmFRAMEIRQ ) { //when first SOF received we can continue 373 | if( delay < millis() ) { //20ms passed 374 | usb_task_state = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE; 375 | } 376 | } 377 | break; 378 | case USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE: 379 | // toggle( BPNT_0 ); 380 | devtable[ 0 ].epinfo->MaxPktSize = 8; //set max.packet size to min.allowed 381 | rcode = getDevDescr( 0, 0, 8, ( char* )&buf ); 382 | if( rcode == 0 ) { 383 | devtable[ 0 ].epinfo->MaxPktSize = buf.bMaxPacketSize0; 384 | usb_task_state = USB_STATE_ADDRESSING; 385 | } 386 | else { 387 | usb_error = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE; 388 | usb_task_state = USB_STATE_ERROR; 389 | } 390 | break; 391 | case USB_STATE_ADDRESSING: 392 | for( i = 1; i < USB_NUMDEVICES; i++ ) 393 | { 394 | if( devtable[ i ].epinfo == NULL ) 395 | { 396 | devtable[ i ].epinfo = devtable[ 0 ].epinfo; //set correct MaxPktSize 397 | //temporary record 398 | //until plugged with real device endpoint structure 399 | rcode = setAddr( 0, 0, i ); 400 | if( rcode == 0 ) { 401 | tmpaddr = i; 402 | usb_task_state = USB_STATE_CONFIGURING; 403 | } 404 | else { 405 | usb_error = USB_STATE_ADDRESSING; //set address error 406 | usb_task_state = USB_STATE_ERROR; 407 | } 408 | break; //break if address assigned or error occured during address assignment attempt 409 | } 410 | }//for( i = 1; i < USB_NUMDEVICES; i++ 411 | if( usb_task_state == USB_STATE_ADDRESSING ) { //no vacant place in devtable 412 | usb_error = 0xfe; 413 | usb_task_state = USB_STATE_ERROR; 414 | } 415 | break; 416 | case USB_STATE_CONFIGURING: 417 | break; 418 | case USB_STATE_RUNNING: 419 | break; 420 | case USB_STATE_ERROR: 421 | break; 422 | }// switch( usb_task_state 423 | } 424 | -------------------------------------------------------------------------------- /Usb.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com */ 2 | /* USB functions */ 3 | #ifndef _usb_h_ 4 | #define _usb_h_ 5 | 6 | #include 7 | #include "ch9.h" 8 | 9 | /* Common setup data constant combinations */ 10 | #define bmREQ_GET_DESCR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE //get descriptor request type 11 | #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' 12 | #define bmREQ_CL_GET_INTF USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE //get interface request type 13 | /* HID requests */ 14 | #define bmREQ_HIDOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE 15 | #define bmREQ_HIDIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE 16 | #define bmREQ_HIDREPORT USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_INTERFACE 17 | 18 | #define USB_XFER_TIMEOUT 5000 //USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec 19 | #define USB_NAK_LIMIT 32000 //NAK limit for a transfer. o meand NAKs are not counted 20 | #define USB_RETRY_LIMIT 3 //retry limit for a transfer 21 | #define USB_SETTLE_DELAY 200 //settle delay in milliseconds 22 | #define USB_NAK_NOWAIT 1 //used in Richard's PS2/Wiimote code 23 | 24 | #define USB_NUMDEVICES 2 //number of USB devices 25 | 26 | /* USB state machine states */ 27 | 28 | #define USB_STATE_MASK 0xf0 29 | 30 | #define USB_STATE_DETACHED 0x10 31 | #define USB_DETACHED_SUBSTATE_INITIALIZE 0x11 32 | #define USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE 0x12 33 | #define USB_DETACHED_SUBSTATE_ILLEGAL 0x13 34 | #define USB_ATTACHED_SUBSTATE_SETTLE 0x20 35 | #define USB_ATTACHED_SUBSTATE_RESET_DEVICE 0x30 36 | #define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE 0x40 37 | #define USB_ATTACHED_SUBSTATE_WAIT_SOF 0x50 38 | #define USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE 0x60 39 | #define USB_STATE_ADDRESSING 0x70 40 | #define USB_STATE_CONFIGURING 0x80 41 | #define USB_STATE_RUNNING 0x90 42 | #define USB_STATE_ERROR 0xa0 43 | 44 | // byte usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE 45 | 46 | /* USB Setup Packet Structure */ 47 | typedef struct { 48 | union { // offset description 49 | byte bmRequestType; // 0 Bit-map of request type 50 | struct { 51 | byte recipient: 5; // Recipient of the request 52 | byte type: 2; // Type of request 53 | byte direction: 1; // Direction of data X-fer 54 | }; 55 | }ReqType_u; 56 | byte bRequest; // 1 Request 57 | union { 58 | unsigned int wValue; // 2 Depends on bRequest 59 | struct { 60 | byte wValueLo; 61 | byte wValueHi; 62 | }; 63 | }wVal_u; 64 | unsigned int wIndex; // 4 Depends on bRequest 65 | unsigned int wLength; // 6 Depends on bRequest 66 | } SETUP_PKT, *PSETUP_PKT; 67 | 68 | /* Endpoint information structure */ 69 | /* bToggle of endpoint 0 initialized to 0xff */ 70 | /* during enumeration bToggle is set to 00 */ 71 | typedef struct { 72 | byte epAddr; //copy from endpoint descriptor. Bit 7 indicates direction ( ignored for control endpoints ) 73 | byte Attr; // Endpoint transfer type. 74 | unsigned int MaxPktSize; // Maximum packet size. 75 | byte Interval; // Polling interval in frames. 76 | byte sndToggle; //last toggle value, bitmask for HCTL toggle bits 77 | byte rcvToggle; //last toggle value, bitmask for HCTL toggle bits 78 | /* not sure if both are necessary */ 79 | } EP_RECORD; 80 | /* device record structure */ 81 | typedef struct { 82 | EP_RECORD* epinfo; //device endpoint information 83 | byte devclass; //device class 84 | } DEV_RECORD; 85 | 86 | 87 | 88 | class USB : public MAX3421E { 89 | //data structures 90 | /* device table. Filled during enumeration */ 91 | /* index corresponds to device address */ 92 | /* each entry contains pointer to endpoint structure */ 93 | /* and device class to use in various places */ 94 | //DEV_RECORD devtable[ USB_NUMDEVICES + 1 ]; 95 | //EP_RECORD dev0ep; //Endpoint data structure used during enumeration for uninitialized device 96 | 97 | //byte usb_task_state; 98 | 99 | public: 100 | USB( void ); 101 | byte getUsbTaskState( void ); 102 | void setUsbTaskState( byte state ); 103 | EP_RECORD* getDevTableEntry( byte addr, byte ep ); 104 | void setDevTableEntry( byte addr, EP_RECORD* eprecord_ptr ); 105 | byte ctrlReq( byte addr, byte ep, byte bmReqType, byte bRequest, byte wValLo, byte wValHi, unsigned int wInd, unsigned int nbytes, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 106 | /* Control requests */ 107 | byte getDevDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 108 | byte getConfDescr( byte addr, byte ep, unsigned int nbytes, byte conf, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 109 | byte getStrDescr( byte addr, byte ep, unsigned int nbytes, byte index, unsigned int langid, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 110 | byte setAddr( byte oldaddr, byte ep, byte newaddr, unsigned int nak_limit = USB_NAK_LIMIT ); 111 | byte setConf( byte addr, byte ep, byte conf_value, unsigned int nak_limit = USB_NAK_LIMIT ); 112 | /**/ 113 | byte setProto( byte addr, byte ep, byte interface, byte protocol, unsigned int nak_limit = USB_NAK_LIMIT ); 114 | byte getProto( byte addr, byte ep, byte interface, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 115 | byte getReportDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 116 | byte setReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 117 | byte getReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 118 | byte getIdle( byte addr, byte ep, byte interface, byte reportID, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 119 | byte setIdle( byte addr, byte ep, byte interface, byte reportID, byte duration, unsigned int nak_limit = USB_NAK_LIMIT ); 120 | /**/ 121 | byte ctrlData( byte addr, byte ep, unsigned int nbytes, char* dataptr, boolean direction, unsigned int nak_limit = USB_NAK_LIMIT ); 122 | byte ctrlStatus( byte ep, boolean direction, unsigned int nak_limit = USB_NAK_LIMIT ); 123 | byte inTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit = USB_NAK_LIMIT ); 124 | int newInTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit = USB_NAK_LIMIT); 125 | byte outTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit = USB_NAK_LIMIT ); 126 | byte dispatchPkt( byte token, byte ep, unsigned int nak_limit = USB_NAK_LIMIT ); 127 | void Task( void ); 128 | private: 129 | void init(); 130 | }; 131 | 132 | //get device descriptor 133 | inline byte USB::getDevDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit ) { 134 | return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr, nak_limit )); 135 | } 136 | //get configuration descriptor 137 | inline byte USB::getConfDescr( byte addr, byte ep, unsigned int nbytes, byte conf, char* dataptr, unsigned int nak_limit ) { 138 | return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr, nak_limit )); 139 | } 140 | //get string descriptor 141 | inline byte USB::getStrDescr( byte addr, byte ep, unsigned int nbytes, byte index, unsigned int langid, char* dataptr, unsigned int nak_limit ) { 142 | return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nbytes, dataptr, nak_limit )); 143 | } 144 | //set address 145 | inline byte USB::setAddr( byte oldaddr, byte ep, byte newaddr, unsigned int nak_limit ) { 146 | return( ctrlReq( oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL, nak_limit )); 147 | } 148 | //set configuration 149 | inline byte USB::setConf( byte addr, byte ep, byte conf_value, unsigned int nak_limit ) { 150 | return( ctrlReq( addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL, nak_limit )); 151 | } 152 | //class requests 153 | inline byte USB::setProto( byte addr, byte ep, byte interface, byte protocol, unsigned int nak_limit ) { 154 | return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, interface, 0x0000, NULL, nak_limit )); 155 | } 156 | inline byte USB::getProto( byte addr, byte ep, byte interface, char* dataptr, unsigned int nak_limit ) { 157 | return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, interface, 0x0001, dataptr, nak_limit )); 158 | } 159 | //get HID report descriptor 160 | inline byte USB::getReportDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit ) { 161 | return( ctrlReq( addr, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, nbytes, dataptr, nak_limit )); 162 | } 163 | inline byte USB::setReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit ) { 164 | return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit )); 165 | } 166 | inline byte USB::getReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit ) { // ** RI 04/11/09 167 | return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit )); 168 | } 169 | /* returns one byte of data in dataptr */ 170 | inline byte USB::getIdle( byte addr, byte ep, byte interface, byte reportID, char* dataptr, unsigned int nak_limit ) { 171 | return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_IDLE, reportID, 0, interface, 0x0001, dataptr, nak_limit )); 172 | } 173 | inline byte USB::setIdle( byte addr, byte ep, byte interface, byte reportID, byte duration, unsigned int nak_limit ) { 174 | return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID, duration, interface, 0x0000, NULL, nak_limit )); 175 | } 176 | #endif //_usb_h_ 177 | -------------------------------------------------------------------------------- /ch9.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com */ 2 | /* USB chapter 9 structures */ 3 | #ifndef _ch9_h_ 4 | #define _ch9_h_ 5 | 6 | /* Misc.USB constants */ 7 | #define DEV_DESCR_LEN 18 //device descriptor length 8 | #define CONF_DESCR_LEN 9 //configuration descriptor length 9 | #define INTR_DESCR_LEN 9 //interface descriptor length 10 | #define EP_DESCR_LEN 7 //endpoint descriptor length 11 | 12 | /* Standard Device Requests */ 13 | 14 | #define USB_REQUEST_GET_STATUS 0 // Standard Device Request - GET STATUS 15 | #define USB_REQUEST_CLEAR_FEATURE 1 // Standard Device Request - CLEAR FEATURE 16 | #define USB_REQUEST_SET_FEATURE 3 // Standard Device Request - SET FEATURE 17 | #define USB_REQUEST_SET_ADDRESS 5 // Standard Device Request - SET ADDRESS 18 | #define USB_REQUEST_GET_DESCRIPTOR 6 // Standard Device Request - GET DESCRIPTOR 19 | #define USB_REQUEST_SET_DESCRIPTOR 7 // Standard Device Request - SET DESCRIPTOR 20 | #define USB_REQUEST_GET_CONFIGURATION 8 // Standard Device Request - GET CONFIGURATION 21 | #define USB_REQUEST_SET_CONFIGURATION 9 // Standard Device Request - SET CONFIGURATION 22 | #define USB_REQUEST_GET_INTERFACE 10 // Standard Device Request - GET INTERFACE 23 | #define USB_REQUEST_SET_INTERFACE 11 // Standard Device Request - SET INTERFACE 24 | #define USB_REQUEST_SYNCH_FRAME 12 // Standard Device Request - SYNCH FRAME 25 | 26 | #define USB_FEATURE_ENDPOINT_HALT 0 // CLEAR/SET FEATURE - Endpoint Halt 27 | #define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 // CLEAR/SET FEATURE - Device remote wake-up 28 | #define USB_FEATURE_TEST_MODE 2 // CLEAR/SET FEATURE - Test mode 29 | 30 | /* Setup Data Constants */ 31 | 32 | #define USB_SETUP_HOST_TO_DEVICE 0x00 // Device Request bmRequestType transfer direction - host to device transfer 33 | #define USB_SETUP_DEVICE_TO_HOST 0x80 // Device Request bmRequestType transfer direction - device to host transfer 34 | #define USB_SETUP_TYPE_STANDARD 0x00 // Device Request bmRequestType type - standard 35 | #define USB_SETUP_TYPE_CLASS 0x20 // Device Request bmRequestType type - class 36 | #define USB_SETUP_TYPE_VENDOR 0x40 // Device Request bmRequestType type - vendor 37 | #define USB_SETUP_RECIPIENT_DEVICE 0x00 // Device Request bmRequestType recipient - device 38 | #define USB_SETUP_RECIPIENT_INTERFACE 0x01 // Device Request bmRequestType recipient - interface 39 | #define USB_SETUP_RECIPIENT_ENDPOINT 0x02 // Device Request bmRequestType recipient - endpoint 40 | #define USB_SETUP_RECIPIENT_OTHER 0x03 // Device Request bmRequestType recipient - other 41 | 42 | /* USB descriptors */ 43 | 44 | #define USB_DESCRIPTOR_DEVICE 0x01 // bDescriptorType for a Device Descriptor. 45 | #define USB_DESCRIPTOR_CONFIGURATION 0x02 // bDescriptorType for a Configuration Descriptor. 46 | #define USB_DESCRIPTOR_STRING 0x03 // bDescriptorType for a String Descriptor. 47 | #define USB_DESCRIPTOR_INTERFACE 0x04 // bDescriptorType for an Interface Descriptor. 48 | #define USB_DESCRIPTOR_ENDPOINT 0x05 // bDescriptorType for an Endpoint Descriptor. 49 | #define USB_DESCRIPTOR_DEVICE_QUALIFIER 0x06 // bDescriptorType for a Device Qualifier. 50 | #define USB_DESCRIPTOR_OTHER_SPEED 0x07 // bDescriptorType for a Other Speed Configuration. 51 | #define USB_DESCRIPTOR_INTERFACE_POWER 0x08 // bDescriptorType for Interface Power. 52 | #define USB_DESCRIPTOR_OTG 0x09 // bDescriptorType for an OTG Descriptor. 53 | 54 | /* OTG SET FEATURE Constants */ 55 | #define OTG_FEATURE_B_HNP_ENABLE 3 // SET FEATURE OTG - Enable B device to perform HNP 56 | #define OTG_FEATURE_A_HNP_SUPPORT 4 // SET FEATURE OTG - A device supports HNP 57 | #define OTG_FEATURE_A_ALT_HNP_SUPPORT 5 // SET FEATURE OTG - Another port on the A device supports HNP 58 | 59 | /* USB Endpoint Transfer Types */ 60 | #define USB_TRANSFER_TYPE_CONTROL 0x00 // Endpoint is a control endpoint. 61 | #define USB_TRANSFER_TYPE_ISOCHRONOUS 0x01 // Endpoint is an isochronous endpoint. 62 | #define USB_TRANSFER_TYPE_BULK 0x02 // Endpoint is a bulk endpoint. 63 | #define USB_TRANSFER_TYPE_INTERRUPT 0x03 // Endpoint is an interrupt endpoint. 64 | #define bmUSB_TRANSFER_TYPE 0x03 // bit mask to separate transfer type from ISO attributes 65 | 66 | 67 | /* Standard Feature Selectors for CLEAR_FEATURE Requests */ 68 | #define USB_FEATURE_ENDPOINT_STALL 0 // Endpoint recipient 69 | #define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 // Device recipient 70 | #define USB_FEATURE_TEST_MODE 2 // Device recipient 71 | 72 | /* HID constants. Not part of chapter 9 */ 73 | /* Class-Specific Requests */ 74 | #define HID_REQUEST_GET_REPORT 0x01 75 | #define HID_REQUEST_GET_IDLE 0x02 76 | #define HID_REQUEST_GET_PROTOCOL 0x03 77 | #define HID_REQUEST_SET_REPORT 0x09 78 | #define HID_REQUEST_SET_IDLE 0x0A 79 | #define HID_REQUEST_SET_PROTOCOL 0x0B 80 | 81 | /* Class Descriptor Types */ 82 | #define HID_DESCRIPTOR_HID 0x21 83 | #define HID_DESCRIPTOR_REPORT 0x22 84 | #define HID_DESRIPTOR_PHY 0x23 85 | 86 | /* Protocol Selection */ 87 | #define BOOT_PROTOCOL 0x00 88 | #define RPT_PROTOCOL 0x01 89 | /* HID Interface Class Code */ 90 | #define HID_INTF 0x03 91 | /* HID Interface Class SubClass Codes */ 92 | #define BOOT_INTF_SUBCLASS 0x01 93 | /* HID Interface Class Protocol Codes */ 94 | #define HID_PROTOCOL_NONE 0x00 95 | #define HID_PROTOCOL_KEYBOARD 0x01 96 | #define HID_PROTOCOL_MOUSE 0x02 97 | 98 | 99 | /* descriptor data structures */ 100 | 101 | /* Device descriptor structure */ 102 | typedef struct { 103 | byte bLength; // Length of this descriptor. 104 | byte bDescriptorType; // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE). 105 | unsigned int bcdUSB; // USB Spec Release Number (BCD). 106 | byte bDeviceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific. 107 | byte bDeviceSubClass; // Subclass code (assigned by the USB-IF). 108 | byte bDeviceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific. 109 | byte bMaxPacketSize0; // Maximum packet size for endpoint 0. 110 | unsigned int idVendor; // Vendor ID (assigned by the USB-IF). 111 | unsigned int idProduct; // Product ID (assigned by the manufacturer). 112 | unsigned int bcdDevice; // Device release number (BCD). 113 | byte iManufacturer; // Index of String Descriptor describing the manufacturer. 114 | byte iProduct; // Index of String Descriptor describing the product. 115 | byte iSerialNumber; // Index of String Descriptor with the device's serial number. 116 | byte bNumConfigurations; // Number of possible configurations. 117 | } USB_DEVICE_DESCRIPTOR; 118 | 119 | /* Configuration descriptor structure */ 120 | typedef struct 121 | { 122 | byte bLength; // Length of this descriptor. 123 | byte bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION). 124 | unsigned int wTotalLength; // Total length of all descriptors for this configuration. 125 | byte bNumInterfaces; // Number of interfaces in this configuration. 126 | byte bConfigurationValue; // Value of this configuration (1 based). 127 | byte iConfiguration; // Index of String Descriptor describing the configuration. 128 | byte bmAttributes; // Configuration characteristics. 129 | byte bMaxPower; // Maximum power consumed by this configuration. 130 | } USB_CONFIGURATION_DESCRIPTOR; 131 | 132 | /* Interface descriptor structure */ 133 | typedef struct 134 | { 135 | byte bLength; // Length of this descriptor. 136 | byte bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE). 137 | byte bInterfaceNumber; // Number of this interface (0 based). 138 | byte bAlternateSetting; // Value of this alternate interface setting. 139 | byte bNumEndpoints; // Number of endpoints in this interface. 140 | byte bInterfaceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific. 141 | byte bInterfaceSubClass; // Subclass code (assigned by the USB-IF). 142 | byte bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific. 143 | byte iInterface; // Index of String Descriptor describing the interface. 144 | } USB_INTERFACE_DESCRIPTOR; 145 | 146 | /* Endpoint descriptor structure */ 147 | typedef struct 148 | { 149 | byte bLength; // Length of this descriptor. 150 | byte bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT). 151 | byte bEndpointAddress; // Endpoint address. Bit 7 indicates direction (0=OUT, 1=IN). 152 | byte bmAttributes; // Endpoint transfer type. 153 | unsigned int wMaxPacketSize; // Maximum packet size. 154 | byte bInterval; // Polling interval in frames. 155 | } USB_ENDPOINT_DESCRIPTOR; 156 | 157 | /* HID descriptor */ 158 | typedef struct { 159 | byte bLength; 160 | byte bDescriptorType; 161 | unsigned int bcdHID; 162 | byte bCountryCode; 163 | byte bNumDescriptors; 164 | byte bDescrType; 165 | unsigned int wDescriptorLength; 166 | } USB_HID_DESCRIPTOR; 167 | 168 | #endif // _ch9_h_ 169 | -------------------------------------------------------------------------------- /examples/PS3Bluetooth/HCI.ino: -------------------------------------------------------------------------------- 1 | void HCI_event_task() 2 | { 3 | byte rcode = 0; //return code 4 | /* 5 | char char_left; 6 | char result_pointer; 7 | char buf_offset; 8 | */ 9 | /* check the event pipe*/ 10 | rcode = Usb.inTransfer(BT_ADDR, ep_record[ EVENT_PIPE ].epAddr, MAX_BUFFER_SIZE, hcibuf, USB_NAK_NOWAIT); // input on endpoint 1 11 | if ( !rcode) 12 | { 13 | switch (hcibuf[0]){//switch on event type 14 | case EV_COMMAND_COMPLETE: 15 | hci_command_packets = hcibuf[2]; // update flow control 16 | hci_event_flag |= HCI_FLAG_CMD_COMPLETE; // set command complete flag 17 | 18 | // process parameters if any 19 | 20 | if((hcibuf[3] == 0x09) && (hcibuf[4] == 0x10)){ // parameters from read local bluetooth address 21 | for (char i = 0; i < 6; i++) 22 | my_bdaddr[i] = (unsigned char) hcibuf[6 + i]; 23 | } 24 | 25 | if((hcibuf[3] == 0x05) && (hcibuf[4] == 0x10)){ //parameters from read buffer size 26 | acl_data_packet_length = (unsigned char) hcibuf[6] | (unsigned char) hcibuf[7] << 8; 27 | sync_data_packet_length =(unsigned char) hcibuf[8]; 28 | acl_data_packets= (unsigned char) hcibuf[9] | (unsigned char) hcibuf[10] << 8; 29 | sync_data_packets =(unsigned char) hcibuf[11] | (unsigned char) hcibuf[12] << 8; 30 | } 31 | if((hcibuf[3] == 0x01) && (hcibuf[4] == 0x10)){ // parameters from read local version 32 | hci_version = (unsigned char) hcibuf[6]; 33 | hci_revision =(unsigned char) hcibuf[7] | (unsigned char) hcibuf[8] << 8; 34 | lmp_version= (unsigned char) hcibuf[9]; 35 | manufacturer_id = (unsigned char) hcibuf[10] | (unsigned char) hcibuf[11] << 8; 36 | lmp_subversion =(unsigned char) hcibuf[12] | (unsigned char) hcibuf[13] << 8; 37 | } 38 | 39 | if((hcibuf[3] == 0x14) && (hcibuf[4] == 0x0c)){ // parameters from read local name 40 | for (char i = 0; i <20; i++){ // save first 20 bytes 41 | local_name[i] = (unsigned char) hcibuf[6 + i]; 42 | } 43 | 44 | for(char i = 0; i < 3; i++){ // ignore rest 45 | Usb.inTransfer(BT_ADDR, ep_record[ EVENT_PIPE ].epAddr, MAX_BUFFER_SIZE, hcibuf, USB_NAK_NOWAIT); 46 | } 47 | 48 | } 49 | break; 50 | 51 | case EV_COMMAND_STATUS: 52 | 53 | hci_command_packets = hcibuf[3]; // update flow control 54 | hci_event_flag |= HCI_FLAG_CMD_STATUS; //set status flag 55 | if(hcibuf[2]){ // show status on serial if not OK 56 | printProgStr(HCI_Command_Failed_str); 57 | Serial.print(hcibuf[2],HEX); 58 | Serial.print(' '); 59 | Serial.print(hcibuf[4],HEX); 60 | Serial.print(' '); 61 | Serial.print(hcibuf[5],HEX); 62 | 63 | } 64 | break; 65 | 66 | case EV_CONNECT_COMPLETE: 67 | 68 | hci_event_flag |= HCI_FLAG_CONN_COMPLETE; // set connection complete flag 69 | if (!hcibuf[2]){ // check if connected OK 70 | hci_handle = (unsigned char) hcibuf[3] | (unsigned char) hcibuf[4] << 8; //store the handle for the ACL connection 71 | hci_event_flag |= HCI_FLAG_CONNECT_OK; //set connection OK flag 72 | } 73 | break; 74 | 75 | 76 | case EV_DISCONNECT_COMPLETE: 77 | 78 | hci_event_flag |= HCI_FLAG_DISCONN_COMPLETE; //set disconnect commend complete flag 79 | if (!hcibuf[2]){ // check if disconnected OK 80 | hci_event_flag &= ~(HCI_FLAG_CONNECT_OK); //clear connection OK flag 81 | } 82 | break; 83 | 84 | case EV_NUM_COMPLETE_PKT: 85 | acl_outstanding_pkt -= (unsigned char) hcibuf[6] | (unsigned char) hcibuf[7] << 8; 86 | break; 87 | 88 | case EV_REMOTE_NAME_COMPLETE: 89 | 90 | for (char i = 0; i < 30; i++){ 91 | remote_name[remote_name_entry][i] = (unsigned char) hcibuf[9 + i]; //store first 30 bytes 92 | } 93 | for(char i = 0; i < 4; i++){ // discard additional bytes 94 | Usb.inTransfer(BT_ADDR, ep_record[ EVENT_PIPE ].epAddr, MAX_BUFFER_SIZE, hcibuf, USB_NAK_NOWAIT); 95 | } 96 | hci_event_flag |=HCI_FLAG_REMOTE_NAME_COMPLETE; 97 | break; 98 | 99 | case EV_INCOMING_CONNECT: 100 | disc_bdaddr[0][0] = (unsigned char) hcibuf[2]; 101 | disc_bdaddr[0][1] = (unsigned char) hcibuf[3]; 102 | disc_bdaddr[0][2] = (unsigned char) hcibuf[4]; 103 | disc_bdaddr[0][3] = (unsigned char) hcibuf[5]; 104 | disc_bdaddr[0][4] = (unsigned char) hcibuf[6]; 105 | disc_bdaddr[0][5] = (unsigned char) hcibuf[7]; 106 | disc_class[0][0] = (unsigned char) hcibuf[8]; 107 | disc_class[0][1] = (unsigned char) hcibuf[9]; 108 | disc_class[0][2] = (unsigned char) hcibuf[10]; 109 | dev_link_type = (unsigned char) hcibuf[11]; 110 | hci_event_flag |=HCI_FLAG_INCOMING_REQUEST; 111 | break; 112 | 113 | case EV_ROLE_CHANGED: 114 | dev_role = (unsigned char)hcibuf[9]; 115 | //Serial.println("Role Changed"); 116 | break; 117 | default: 118 | if(hcibuf[0] != 0x00) 119 | { 120 | printProgStr(Unmanaged_Event_str); 121 | Serial.println(hcibuf[0],HEX); 122 | } 123 | break; 124 | 125 | } // switch 126 | } 127 | HCI_task(); 128 | } 129 | 130 | /* Poll Bluetooth and print result */ 131 | void HCI_task() 132 | { 133 | switch (hci_state){ 134 | case HCI_INIT_STATE: 135 | hci_counter++; 136 | if (hci_counter > 10){ // wait until we have looped 10 times to clear any old events 137 | hci_reset(); 138 | hci_state = HCI_RESET_STATE; 139 | hci_counter = 0; 140 | } 141 | break; 142 | 143 | case HCI_RESET_STATE: 144 | hci_counter++; 145 | if (hci_cmd_complete){ 146 | hci_state = HCI_BUFFER_SIZE_STATE; 147 | printProgStr(HCI_Reset_str); 148 | hci_read_buffer_size(); 149 | } 150 | if (hci_counter > 1000) { 151 | printProgStr(Reset_Error_str); 152 | hci_state = HCI_INIT_STATE; 153 | hci_counter = 0; 154 | } 155 | break; 156 | 157 | case HCI_BUFFER_SIZE_STATE: 158 | if (hci_cmd_complete){ 159 | printProgStr(ACL_Length_str); 160 | Serial.print(acl_data_packet_length, DEC); 161 | printProgStr(SCO_Length_str); 162 | Serial.print(sync_data_packet_length, DEC); 163 | printProgStr(ACL_Number_str); 164 | Serial.print(acl_data_packets, DEC); 165 | printProgStr(SCO_Number_str); 166 | Serial.print(sync_data_packets, DEC); 167 | hci_state = HCI_LOCAL_VERSION_STATE; 168 | hci_read_local_version(); 169 | } 170 | break; 171 | 172 | 173 | case HCI_LOCAL_VERSION_STATE: 174 | if (hci_cmd_complete){ 175 | printProgStr(HCI_Version_str); 176 | Serial.print(hci_version, DEC); 177 | printProgStr(HCI_Revision_str); 178 | Serial.print(hci_revision, DEC); 179 | printProgStr(LMP_Version_str); 180 | Serial.print(lmp_version, DEC); 181 | printProgStr(Manuf_Id_str); 182 | Serial.print(manufacturer_id, DEC); 183 | printProgStr(LMP_Subvers_str); 184 | Serial.print(lmp_subversion, DEC); 185 | hci_state = HCI_LOCAL_NAME_STATE; 186 | hci_read_local_name(); 187 | } 188 | break; 189 | 190 | case HCI_LOCAL_NAME_STATE: 191 | if (hci_cmd_complete){ 192 | printProgStr(Local_Name_str); 193 | for (char i = 0; i < 20; i++){ 194 | if(local_name[i] == NULL) 195 | break; 196 | Serial.write(local_name[i]); 197 | } 198 | hci_state = HCI_BDADDR_STATE; 199 | hci_read_bdaddr(); 200 | } 201 | break; 202 | 203 | case HCI_BDADDR_STATE: 204 | if (hci_cmd_complete){ 205 | printProgStr(Local_BDADDR_str); 206 | 207 | for(int i = 5; i>0;i--) 208 | { 209 | if(my_bdaddr[i] < 16) 210 | Serial.print("0"); 211 | Serial.print(my_bdaddr[i], HEX); 212 | Serial.print(":"); 213 | } 214 | if (my_bdaddr[0] < 16) 215 | Serial.print("0"); 216 | Serial.print(my_bdaddr[0], HEX); 217 | 218 | hci_state = HCI_SCANNING_STATE; 219 | 220 | } 221 | break; 222 | case HCI_SCANNING_STATE: 223 | printProgStr(Connect_In_str); 224 | hci_write_scan_enable(); 225 | hci_state = HCI_CONNECT_IN_STATE; 226 | break; 227 | 228 | case HCI_CONNECT_IN_STATE: 229 | if(hci_incoming_connect_request) 230 | { 231 | printProgStr(In_Request_str); 232 | remote_name_entry = 0; 233 | hci_remote_name(remote_name_entry); 234 | hci_state = HCI_REMOTE_NAME_STATE; 235 | } 236 | break; 237 | 238 | case HCI_REMOTE_NAME_STATE: 239 | if(hci_remote_name_complete) 240 | { 241 | printProgStr(Remote_Name_str); 242 | for (char i = 0; i < 30; i++) 243 | { 244 | if(remote_name[remote_name_entry][i] == NULL) 245 | break; 246 | Serial.write(remote_name[remote_name_entry][i]); 247 | } 248 | 249 | hci_accept_connection(0); 250 | hci_state = HCI_CONNECTED_STATE; 251 | } 252 | break; 253 | 254 | case HCI_CONNECTED_STATE: 255 | if (hci_connect_complete) 256 | { 257 | printProgStr(Device_Connected_str); 258 | for(int i = 5; i>0;i--) 259 | { 260 | if(disc_bdaddr[0][i] < 16) 261 | Serial.print("0"); 262 | Serial.print(disc_bdaddr[0][i], HEX); 263 | Serial.print(":"); 264 | } 265 | if (disc_bdaddr[0][0] < 16) 266 | Serial.print("0"); 267 | Serial.print(disc_bdaddr[0][0], HEX); 268 | 269 | hci_write_scan_disable();//Only allow one controller 270 | hci_state = HCI_DISABLE_SCAN; 271 | } 272 | break; 273 | 274 | case HCI_DISABLE_SCAN: 275 | if (hci_cmd_complete) 276 | { 277 | printProgStr(Scan_Disabled_str); 278 | l2cap_state = L2CAP_EV_CONTROL_SETUP; 279 | hci_state = HCI_DONE_STATE; 280 | } 281 | break; 282 | 283 | case HCI_DONE_STATE: 284 | if (hci_disconnect_complete) 285 | hci_state = HCI_DISCONNECT_STATE; 286 | break; 287 | 288 | case HCI_DISCONNECT_STATE: 289 | if (hci_disconnect_complete) 290 | { 291 | printProgStr(Device_Disconnected_str); 292 | 293 | for(int i = 5; i>0;i--) 294 | { 295 | if(disc_bdaddr[0][i] < 16) 296 | Serial.print("0"); 297 | Serial.print(disc_bdaddr[0][i], HEX); 298 | Serial.print(":"); 299 | } 300 | if (disc_bdaddr[0][0] < 16) 301 | Serial.print("0"); 302 | Serial.print(disc_bdaddr[0][0], HEX); 303 | 304 | l2cap_event_flag = 0;//Clear all flags 305 | hci_event_flag = 0;//Clear all flags 306 | 307 | //Reset all buffers 308 | for (byte i = 0; i < MAX_BUFFER_SIZE; i++) 309 | hcibuf[i] = 0; 310 | for (byte i = 0; i < MAX_BUFFER_SIZE; i++) 311 | l2capinbuf[i] = 0; 312 | for (byte i = 0; i < MAX_BUFFER_SIZE; i++) 313 | l2capoutbuf[i] = 0; 314 | 315 | for (int i = 0; i < OUTPUT_REPORT_BUFFER_SIZE; i++) 316 | HIDBuffer[i + 2] = pgm_read_byte(&OUTPUT_REPORT_BUFFER[i]);//First two bytes reserved for report type and ID 317 | for (byte i = 2; i < HIDMoveBufferSize; i++) 318 | HIDMoveBuffer[i] = 0; 319 | 320 | l2cap_state = L2CAP_EV_WAIT; 321 | hci_state = HCI_SCANNING_STATE; 322 | } 323 | break; 324 | default: 325 | break; 326 | } 327 | } 328 | 329 | 330 | 331 | 332 | -------------------------------------------------------------------------------- /examples/PS3Bluetooth/HCI_Commands.ino: -------------------------------------------------------------------------------- 1 | // used in control endpoint header for HCI Commands 2 | #define bmREQ_HCI_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE 3 | #define HCI_COMMAND_REQ 0 4 | 5 | /************************************************************/ 6 | /* HCI Commands */ 7 | /************************************************************/ 8 | 9 | //perform HCI Command 10 | void HCI_Command(char* dataptr, unsigned int nbytes) 11 | { 12 | hci_command_packets--; 13 | hci_event_flag &= ~HCI_FLAG_CMD_COMPLETE; 14 | Usb.ctrlReq( BT_ADDR, ep_record[ CONTROL_PIPE ].epAddr, bmREQ_HCI_OUT, HCI_COMMAND_REQ, 0x00, 0x00 ,0, nbytes, dataptr ); 15 | } 16 | 17 | void hci_reset() 18 | { 19 | hci_event_flag = 0; // clear all the flags 20 | hcibuf[0] = 0x03; // HCI OCF = 3 21 | hcibuf[1] = 0x03 << 2; // HCI OGF = 3 22 | hcibuf[2] = 0x00; 23 | HCI_Command(hcibuf, 3); 24 | } 25 | void hci_read_buffer_size() 26 | { 27 | hcibuf[0] = 0x05; // HCI OCF = 5 28 | hcibuf[1] = 0x04 << 2; // HCI OGF = 4 29 | hcibuf[2] = 0x00; 30 | HCI_Command(hcibuf, 3); 31 | } 32 | 33 | void hci_read_local_version() 34 | { 35 | hcibuf[0] = 0x01; // HCI OCF = 1 36 | hcibuf[1] = 0x04 << 2; // HCI OGF = 4 37 | hcibuf[2] = 0x00; 38 | HCI_Command(hcibuf, 3); 39 | } 40 | 41 | 42 | void hci_read_local_name() 43 | { 44 | hcibuf[0] = 0x14; // HCI OCF = 14 45 | hcibuf[1] = 0x03 << 2; // HCI OGF = 3 46 | hcibuf[2] = 0x00; 47 | HCI_Command(hcibuf, 3); 48 | } 49 | 50 | void hci_write_scan_enable() 51 | { 52 | hcibuf[0] = 0x1A; // HCI OCF = 1A 53 | hcibuf[1] = 0x03 << 2; // HCI OGF = 3 54 | hcibuf[2] = 0x01;// parameter length = 1 55 | hcibuf[3] = 0x02;// Inquiry Scan disabled. Page Scan enabled. 56 | HCI_Command(hcibuf, 4); 57 | } 58 | void hci_write_scan_disable() 59 | { 60 | hcibuf[0] = 0x1A; // HCI OCF = 1A 61 | hcibuf[1] = 0x03 << 2; // HCI OGF = 3 62 | hcibuf[2] = 0x01;// parameter length = 1 63 | hcibuf[3] = 0x00;// Inquiry Scan disabled. Page Scan disabled. 64 | HCI_Command(hcibuf, 4); 65 | } 66 | void hci_read_bdaddr() 67 | { 68 | hcibuf[0] = 0x09; // HCI OCF = 9 69 | hcibuf[1] = 0x04 << 2; // HCI OGF = 4 70 | hcibuf[2] = 0x00; 71 | HCI_Command(hcibuf, 3); 72 | } 73 | void hci_accept_connection(char disc_device) 74 | { 75 | hci_event_flag |= HCI_FLAG_CONNECT_OK; 76 | hci_event_flag &= ~(HCI_FLAG_INCOMING_REQUEST); 77 | 78 | hcibuf[0] = 0x09; // HCI OCF = 9 79 | hcibuf[1] = 0x01 << 2; // HCI OGF = 1 80 | hcibuf[2] = 0x07; // parameter length 7 81 | hcibuf[3] = disc_bdaddr[disc_device][0]; // 6 octet bdaddr 82 | hcibuf[4] = disc_bdaddr[disc_device][1]; 83 | hcibuf[5] = disc_bdaddr[disc_device][2]; 84 | hcibuf[6] = disc_bdaddr[disc_device][3]; 85 | hcibuf[7] = disc_bdaddr[disc_device][4]; 86 | hcibuf[8] = disc_bdaddr[disc_device][5]; 87 | hcibuf[9] = 0; //switch role to master 88 | 89 | HCI_Command(hcibuf, 10); 90 | } 91 | 92 | 93 | void hci_remote_name(char disc_device) 94 | { 95 | hci_event_flag &= ~(HCI_FLAG_REMOTE_NAME_COMPLETE); 96 | hcibuf[0] = 0x19; // HCI OCF = 19 97 | hcibuf[1] = 0x01 << 2; // HCI OGF = 1 98 | hcibuf[2] = 0x0A; // parameter length = 10 99 | hcibuf[3] = disc_bdaddr[disc_device][0]; // 6 octet bdaddr 100 | hcibuf[4] = disc_bdaddr[disc_device][1]; 101 | hcibuf[5] = disc_bdaddr[disc_device][2]; 102 | hcibuf[6] = disc_bdaddr[disc_device][3]; 103 | hcibuf[7] = disc_bdaddr[disc_device][4]; 104 | hcibuf[8] = disc_bdaddr[disc_device][5]; 105 | hcibuf[9] = disc_mode[disc_device]; 106 | hcibuf[10] = 0x00; // always 0 107 | hcibuf[11] = 0x00; // offset 108 | hcibuf[12] = 0x00; 109 | 110 | HCI_Command(hcibuf, 13); 111 | } 112 | void hci_disconnect() 113 | { 114 | hci_event_flag &= ~HCI_FLAG_DISCONN_COMPLETE; 115 | hcibuf[0] = 0x06; // HCI OCF = 6 116 | hcibuf[1]= 0x01 << 2; // HCI OGF = 1 117 | hcibuf[2] = 0x03; // parameter length =3 118 | hcibuf[3] = (char)(hci_handle & 0xFF);//connection handle - low byte 119 | hcibuf[4] = (char)((hci_handle >> 8) & 0x0F);//connection handle - high byte 120 | hcibuf[5] = 0x13; // reason 121 | 122 | HCI_Command(hcibuf, 6); 123 | } 124 | 125 | -------------------------------------------------------------------------------- /examples/PS3Bluetooth/HID_Commands.ino: -------------------------------------------------------------------------------- 1 | /* HCI ACL Data Packet 2 | * 3 | * buf[0] buf[1] buf[2] buf[3] 4 | * 0 4 8 11 12 16 24 31 MSB 5 | * .-+-+-+-+-+-+-+-|-+-+-+-|-+-|-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. 6 | * | HCI Handle |PB |BC | Data Total Length | HCI ACL Data Packet 7 | * .-+-+-+-+-+-+-+-|-+-+-+-|-+-|-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. 8 | * 9 | * buf[4] buf[5] buf[6] buf[7] 10 | * 0 8 16 31 MSB 11 | * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. 12 | * | Length | Channel ID | Basic L2CAP header 13 | * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. 14 | * 15 | * buf[8] buf[9] buf[10] buf[11] 16 | * 0 8 16 31 MSB 17 | * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. 18 | * | Code | Identifier | Length | Control frame (C-frame) 19 | * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. (signaling packet format) 20 | */ 21 | 22 | /************************************************************/ 23 | /* HID Commands */ 24 | /************************************************************/ 25 | 26 | //Playstation Sixaxis Dualshoch Controller commands 27 | void HID_Command(char* data, unsigned int length) 28 | { 29 | char buf[64]; 30 | buf[0] = (char)(hci_handle & 0xff); // HCI handle with PB,BC flag 31 | buf[1] = (char)(((hci_handle >> 8) & 0x0f) | 0x20); 32 | buf[2] = (char)((4 + length) & 0xff); // HCI ACL total data length 33 | buf[3] = (char)((4 + length) >> 8); 34 | buf[4] = (char)(length & 0xff); // L2CAP header: Length 35 | buf[5] = (char)(length >> 8); 36 | buf[6] = control_scid[0];//Both the Navigation and Dualshock controller sends data via the controller channel 37 | buf[7] = control_scid[1]; 38 | 39 | for (unsigned int i = 0; i < length; i++)//L2CAP C-frame 40 | buf[8 + i] = data[i]; 41 | 42 | dtimeHID = millis() - timerHID; 43 | 44 | if (dtimeHID <= 250)// Check if is has been more than 250ms since last command 45 | delay((int)(250 - dtimeHID));//There have to be a delay between commands 46 | 47 | Usb.outTransfer(BT_ADDR, ep_record[ DATAOUT_PIPE ].epAddr, (8 + length), buf); 48 | 49 | timerHID = millis(); 50 | } 51 | void hid_setAllOff() 52 | { 53 | for (int i = 0; i < OUTPUT_REPORT_BUFFER_SIZE; i++) 54 | HIDBuffer[i + 2] = pgm_read_byte(&OUTPUT_REPORT_BUFFER[i]);//First two bytes reserved for report type and ID 55 | 56 | HID_Command(HIDBuffer, OUTPUT_REPORT_BUFFER_SIZE + 2); 57 | } 58 | void hid_setRumbleOff() 59 | { 60 | HIDBuffer[3] = 0x00; 61 | HIDBuffer[4] = 0x00;//low mode off 62 | HIDBuffer[5] = 0x00; 63 | HIDBuffer[6] = 0x00;//high mode off 64 | 65 | HID_Command(HIDBuffer, OUTPUT_REPORT_BUFFER_SIZE + 2); 66 | } 67 | void hid_setRumbleOn(Rumble mode) 68 | { 69 | /* Still not totally sure how it works, maybe something like this instead? 70 | * 3 - duration_right 71 | * 4 - power_right 72 | * 5 - duration_left 73 | * 6 - power_left 74 | */ 75 | if (((unsigned int)mode & 0x30) > 0) 76 | { 77 | HIDBuffer[3] = 0xfe; 78 | HIDBuffer[5] = 0xfe; 79 | 80 | if (mode == RumbleHigh) 81 | { 82 | HIDBuffer[4] = 0;//low mode off 83 | HIDBuffer[6] = 0xff;//high mode on 84 | } 85 | else 86 | { 87 | HIDBuffer[4] = 0xff;//low mode on 88 | HIDBuffer[6] = 0;//high mode off 89 | } 90 | 91 | HID_Command(HIDBuffer, OUTPUT_REPORT_BUFFER_SIZE + 2); 92 | } 93 | } 94 | void hid_setLedOff(LED a) 95 | { 96 | //check if LED is already off 97 | if ((char)((char)(((unsigned int)a << 1) & HIDBuffer[11])) != 0) 98 | { 99 | //set the LED into the write buffer 100 | HIDBuffer[11] = (byte)((byte)(((unsigned int)a & 0x0f) << 1) ^ HIDBuffer[11]); 101 | 102 | HID_Command(HIDBuffer, OUTPUT_REPORT_BUFFER_SIZE + 2); 103 | } 104 | } 105 | void hid_setLedOn(LED a) 106 | { 107 | HIDBuffer[11] = (char)((char)(((unsigned int)a & 0x0f) << 1) | HIDBuffer[11]); 108 | 109 | HID_Command(HIDBuffer, OUTPUT_REPORT_BUFFER_SIZE + 2); 110 | } 111 | void hid_enable_sixaxis()//Command used to enable the Dualshock 3 and Navigation controller 112 | { 113 | char cmd_buf[12]; 114 | cmd_buf[0] = 0x53;// HID BT Set_report (0x50) | Report Type (Feature 0x03) 115 | cmd_buf[1] = 0xF4;// Report ID 116 | cmd_buf[2] = 0x42;// Special PS3 Controller enable commands 117 | cmd_buf[3] = 0x03; 118 | cmd_buf[4] = 0x00; 119 | cmd_buf[5] = 0x00; 120 | 121 | HID_Command(cmd_buf, 6); 122 | } 123 | 124 | //Playstation Move Controller commands 125 | void HIDMove_Command(char* data, unsigned int length) 126 | { 127 | char buf[64]; 128 | buf[0] = (char)(hci_handle & 0xff); // HCI handle with PB,BC flag 129 | buf[1] = (char)(((hci_handle >> 8) & 0x0f) | 0x20); 130 | buf[2] = (char)((4 + length) & 0xff); // HCI ACL total data length 131 | buf[3] = (char)((4 + length) >> 8); 132 | buf[4] = (char)(length & 0xff); // L2CAP header: Length 133 | buf[5] = (char)(length >> 8); 134 | buf[6] = interrupt_scid[0];//The Move controller sends it's data via the intterrupt channel 135 | buf[7] = interrupt_scid[1]; 136 | 137 | for (unsigned int i = 0; i < length; i++)//L2CAP C-frame 138 | buf[8 + i] = data[i]; 139 | 140 | dtimeHID = millis() - timerHID; 141 | 142 | if (dtimeHID <= 250)// Check if is has been less than 200ms since last command 143 | delay((int)(250 - dtimeHID));//There have to be a delay between commands 144 | 145 | Usb.outTransfer(BT_ADDR, ep_record[ DATAOUT_PIPE ].epAddr, (8 + length), buf); 146 | 147 | timerHID = millis(); 148 | } 149 | void hid_MoveSetBulb(char r, char g, char b)//Use this to set the Color using RGB values 150 | { 151 | //set the Bulb's values into the write buffer 152 | HIDMoveBuffer[3] = r; 153 | HIDMoveBuffer[4] = g; 154 | HIDMoveBuffer[5] = b; 155 | 156 | HIDMove_Command(HIDMoveBuffer, HIDMoveBufferSize); 157 | } 158 | void hid_MoveSetBulb(Colors color)//Use this to set the Color using the predefined colors in "enums.h" 159 | { 160 | //set the Bulb's values into the write buffer 161 | HIDMoveBuffer[3] = (char)(color >> 16); 162 | HIDMoveBuffer[4] = (char)(color >> 8); 163 | HIDMoveBuffer[5] = (char)(color); 164 | 165 | HIDMove_Command(HIDMoveBuffer, HIDMoveBufferSize); 166 | } 167 | void hid_MoveSetRumble(char rumble) 168 | { 169 | //set the rumble value into the write buffer 170 | HIDMoveBuffer[7] = rumble; 171 | 172 | HIDMove_Command(HIDMoveBuffer, HIDMoveBufferSize); 173 | } 174 | 175 | 176 | -------------------------------------------------------------------------------- /examples/PS3Bluetooth/L2CAP.ino: -------------------------------------------------------------------------------- 1 | void ACL_event_task() 2 | { 3 | Usb.inTransfer(BT_ADDR, ep_record[ DATAIN_PIPE ].epAddr, MAX_BUFFER_SIZE, l2capinbuf, USB_NAK_NOWAIT); // input on endpoint 2 4 | if (((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000)))//acl_handle_ok 5 | { 6 | if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001)//l2cap_control - Channel ID for ACL-U 7 | { 8 | if (l2capinbuf[8] != 0x00) 9 | { 10 | //Serial.print("L2CAP Signaling Command - 0x");Serial.println(l2capinbuf[8],HEX); 11 | } 12 | if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) 13 | { 14 | printProgStr(Cmd_Reject_str); 15 | Serial.print(String(String((unsigned char)l2capinbuf[13],HEX) + " " + String((unsigned char)l2capinbuf[12],HEX) + " Data: " + String((unsigned char)l2capinbuf[17],HEX) + " " + String((unsigned char)l2capinbuf[16],HEX) + " " + String((unsigned char)l2capinbuf[15],HEX) + " " + String((unsigned char)l2capinbuf[14],HEX))); 16 | } 17 | else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) 18 | { 19 | //Serial.print(String("\r\nPSM: 0x" + String((unsigned char)l2capinbuf[13],HEX) + " " + String((unsigned char)l2capinbuf[12],HEX) + " SCID: 0x" + String((unsigned char)l2capinbuf[15],HEX) + " " + String((unsigned char)l2capinbuf[14],HEX))); 20 | if ((l2capinbuf[13] | l2capinbuf[12]) == L2CAP_PSM_HID_CTRL) 21 | { 22 | identifier = l2capinbuf[9]; 23 | control_scid[0] = l2capinbuf[14]; 24 | control_scid[1] = l2capinbuf[15]; 25 | l2cap_event_flag |= L2CAP_EV_CONTROL_CONNECTION_REQUEST; 26 | } 27 | else if ((l2capinbuf[13] | l2capinbuf[12]) == L2CAP_PSM_HID_INTR) 28 | { 29 | identifier = l2capinbuf[9]; 30 | interrupt_scid[0] = l2capinbuf[14]; 31 | interrupt_scid[1] = l2capinbuf[15]; 32 | l2cap_event_flag |= L2CAP_EV_INTERRUPT_CONNECTION_REQUEST; 33 | } 34 | } 35 | else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) 36 | { 37 | if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) 38 | { 39 | if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000)//Success 40 | { 41 | //Serial.println("HID Control Configuration Complete"); 42 | l2cap_event_flag |= L2CAP_EV_CONTROL_CONFIG_SUCCESS; 43 | } 44 | } 45 | else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) 46 | { 47 | if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000)//Success 48 | { 49 | //Serial.println("HID Interrupt Configuration Complete"); 50 | l2cap_event_flag |= L2CAP_EV_INTERRUPT_CONFIG_SUCCESS; 51 | } 52 | } 53 | } 54 | else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) 55 | { 56 | if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) 57 | { 58 | //Serial.println("HID Control Configuration Request"); 59 | identifier = l2capinbuf[9]; 60 | l2cap_event_flag |= L2CAP_EV_CONTROL_CONFIG_REQUEST; 61 | } 62 | else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) 63 | { 64 | //Serial.println("HID Interrupt Configuration Request"); 65 | identifier = l2capinbuf[9]; 66 | l2cap_event_flag |= L2CAP_EV_INTERRUPT_CONFIG_REQUEST; 67 | } 68 | } 69 | else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) 70 | { 71 | if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) 72 | { 73 | printProgStr(Disconnet_Req_Control_str); 74 | } 75 | else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) 76 | { 77 | printProgStr(Disconnet_Req_Interrupt_str); 78 | } 79 | } 80 | else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) 81 | { 82 | if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) 83 | { 84 | //Serial.println("Disconnected Response: Disconnected Control"); 85 | identifier = l2capinbuf[9]; 86 | l2cap_event_flag |= L2CAP_EV_CONTROL_DISCONNECT_RESPONSE; 87 | } 88 | else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) 89 | { 90 | //Serial.println("Disconnected Response: Disconnected Interrupt"); 91 | identifier = l2capinbuf[9]; 92 | l2cap_event_flag |= L2CAP_EV_INTERRUPT_DISCONNECT_RESPONSE; 93 | } 94 | } 95 | } 96 | else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1])//l2cap_interrupt 97 | { 98 | //Serial.println("L2CAP Interrupt"); 99 | if(PS3BTConnected || PS3MoveBTConnected || PS3NavigationBTConnected) 100 | { 101 | readReport(); 102 | //printReport();//Uncomment for debugging 103 | } 104 | } 105 | L2CAP_task(); 106 | } 107 | } 108 | void L2CAP_task() 109 | { 110 | switch (l2cap_state) 111 | { 112 | case L2CAP_EV_WAIT: 113 | break; 114 | case L2CAP_EV_CONTROL_SETUP: 115 | if (l2cap_control_connection_reguest) 116 | { 117 | printProgStr(HID_Control_Connect_Req_str); 118 | l2cap_connection_response(identifier, control_dcid, control_scid, PENDING); 119 | l2cap_connection_response(identifier, control_dcid, control_scid, SUCCESSFUL); 120 | identifier++; 121 | l2cap_config_request(identifier, control_scid); 122 | 123 | l2cap_state = L2CAP_EV_CONTROL_REQUEST; 124 | } 125 | break; 126 | case L2CAP_EV_CONTROL_REQUEST: 127 | if (l2cap_control_config_reguest) 128 | { 129 | printProgStr(HID_Control_Config_Req_str); 130 | l2cap_config_response(identifier, control_scid); 131 | l2cap_state = L2CAP_EV_CONTROL_SUCCESS; 132 | } 133 | break; 134 | 135 | case L2CAP_EV_CONTROL_SUCCESS: 136 | if (l2cap_control_config_success) 137 | { 138 | printProgStr(HID_Control_Success_str); 139 | l2cap_state = L2CAP_EV_INTERRUPT_SETUP; 140 | } 141 | break; 142 | case L2CAP_EV_INTERRUPT_SETUP: 143 | if (l2cap_interrupt_connection_reguest) 144 | { 145 | printProgStr(HID_Interrupt_Connect_Req_str); 146 | l2cap_connection_response(identifier, interrupt_dcid, interrupt_scid, PENDING); 147 | l2cap_connection_response(identifier, interrupt_dcid, interrupt_scid, SUCCESSFUL); 148 | identifier++; 149 | l2cap_config_request(identifier, interrupt_scid); 150 | 151 | l2cap_state = L2CAP_EV_INTERRUPT_REQUEST; 152 | } 153 | break; 154 | case L2CAP_EV_INTERRUPT_REQUEST: 155 | if (l2cap_interrupt_config_reguest) 156 | { 157 | printProgStr(HID_Interrupt_Config_Req_str); 158 | l2cap_config_response(identifier, interrupt_scid); 159 | l2cap_state = L2CAP_EV_INTERRUPT_SUCCESS; 160 | } 161 | break; 162 | case L2CAP_EV_INTERRUPT_SUCCESS: 163 | if (l2cap_interrupt_config_success) 164 | { 165 | printProgStr(HID_Interrupt_Success_str); 166 | l2cap_state = L2CAP_EV_HID_ENABLE_SIXAXIS; 167 | } 168 | break; 169 | case L2CAP_EV_HID_ENABLE_SIXAXIS: 170 | delay(1000); 171 | 172 | if (remote_name[0][0] == 'P')//First letter in PLAYSTATION(R)3 Controller ('P') - 0x50 173 | { 174 | hid_enable_sixaxis(); 175 | hid_setLedOn(LED1); 176 | 177 | for (byte i = 15; i < 19; i++) 178 | l2capinbuf[i] = 0x7F;//Set the analog joystick values to center position 179 | l2capinbuf[12] = 0x00;//reset the 12 byte, as the program sometimes read it as a button has been pressed 180 | 181 | delay(1000);//There has to be a delay before data can be read 182 | printProgStr(Dualshock_Enabled_str); 183 | PS3BTConnected = true; 184 | } 185 | else if (remote_name[0][0] == 'N')//First letter in Navigation Controller ('N') - 0x4E 186 | { 187 | hid_enable_sixaxis(); 188 | hid_setLedOn(LED1);//This just turns LED constantly on, on the Navigation controller 189 | 190 | for (byte i = 15; i < 19; i++) 191 | l2capinbuf[i] = 0x7F;//Set the analog joystick values to center 192 | l2capinbuf[12] = 0x00;//reset the 12 byte, as the program sometimes read it as a button has been pressed 193 | 194 | delay(1000);//There has to be a delay before data can be read 195 | printProgStr(Navigation_Enabled_str); 196 | PS3NavigationBTConnected = true; 197 | } 198 | else if (remote_name[0][0] == 'M')//First letter in Motion Controller ('M') - 0x4D 199 | { 200 | hid_MoveSetBulb(Red); 201 | delay(100); 202 | hid_MoveSetBulb(Green); 203 | delay(100); 204 | hid_MoveSetBulb(Blue); 205 | delay(100); 206 | 207 | hid_MoveSetBulb(Yellow); 208 | delay(100); 209 | hid_MoveSetBulb(Lightblue); 210 | delay(100); 211 | hid_MoveSetBulb(Purble); 212 | delay(100); 213 | 214 | hid_MoveSetBulb(White); 215 | delay(100); 216 | hid_MoveSetBulb(Off); 217 | 218 | l2capinbuf[12] = 0x00;//reset the 12 byte, as the program sometimes read it as the PS_Move button has been pressed 219 | 220 | delay(1000);//There has to be a delay before data can be read 221 | printProgStr(Motion_Enabled_str); 222 | PS3MoveBTConnected = true; 223 | 224 | timerBulbRumble = millis(); 225 | } 226 | l2cap_state = L2CAP_EV_L2CAP_DONE; 227 | break; 228 | 229 | case L2CAP_EV_L2CAP_DONE: 230 | if (PS3MoveBTConnected)//The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on 231 | { 232 | dtimeBulbRumble = millis() - timerBulbRumble; 233 | if (dtimeBulbRumble > 4000)//Send at least every 4th second 234 | { 235 | HIDMove_Command(HIDMoveBuffer, HIDMoveBufferSize);//The Bulb and rumble values, has to be written again and again, for it to stay turned on 236 | timerBulbRumble = millis(); 237 | } 238 | } 239 | break; 240 | 241 | case L2CAP_EV_INTERRUPT_DISCONNECT: 242 | if (l2cap_interrupt_disconnect_response) 243 | { 244 | printProgStr(Interrupt_Disconnected_str); 245 | identifier++; 246 | l2cap_disconnection_request(identifier, control_dcid, control_scid); 247 | l2cap_state = L2CAP_EV_CONTROL_DISCONNECT; 248 | } 249 | break; 250 | 251 | case L2CAP_EV_CONTROL_DISCONNECT: 252 | if (l2cap_control_disconnect_response) 253 | { 254 | printProgStr(Control_Disconnected_str); 255 | hci_disconnect(); 256 | l2cap_state = L2CAP_EV_L2CAP_DONE; 257 | hci_state = HCI_DISCONNECT_STATE; 258 | } 259 | break; 260 | } 261 | } 262 | 263 | /************************************************************/ 264 | /* HID Report (HCI ACL Packet) */ 265 | /************************************************************/ 266 | void readReport() 267 | { 268 | if((unsigned char)l2capinbuf[8] == 0xA1)//HID_THDR_DATA_INPUT 269 | { 270 | if(PS3BTConnected || PS3NavigationBTConnected) 271 | ButtonState = (unsigned long)((unsigned char)l2capinbuf[11] | ((unsigned int)((unsigned char)l2capinbuf[12]) << 8) | ((unsigned long)((unsigned char)l2capinbuf[13]) << 16)); 272 | else if(PS3MoveBTConnected) 273 | ButtonState = (unsigned long)((unsigned char)l2capinbuf[10] | ((unsigned int)((unsigned char)l2capinbuf[11]) << 8) | ((unsigned long)((unsigned char)l2capinbuf[12]) << 16)); 274 | 275 | //Serial.println(ButtonState,HEX); 276 | 277 | if(ButtonState != OldButtonState) 278 | ButtonChanged = true; 279 | else 280 | ButtonChanged = false; 281 | 282 | OldButtonState = ButtonState; 283 | } 284 | } 285 | 286 | void printReport()//Uncomment for debugging 287 | { 288 | if((unsigned char)l2capinbuf[8] == 0xA1)//HID_THDR_DATA_INPUT 289 | { 290 | for(int i = 10; i < 58;i++) 291 | { 292 | if((unsigned char)l2capinbuf[i] < 16) 293 | Serial.print("0"); 294 | Serial.print((unsigned char)l2capinbuf[i],HEX); 295 | Serial.print(" "); 296 | } 297 | Serial.println(""); 298 | } 299 | } 300 | -------------------------------------------------------------------------------- /examples/PS3Bluetooth/L2CAP_Commands.ino: -------------------------------------------------------------------------------- 1 | /************************************************************/ 2 | /* L2CAP Commands */ 3 | /************************************************************/ 4 | void L2CAP_Command(char* data, int length) 5 | { 6 | char buf[64]; 7 | buf[0] = (char)(hci_handle & 0xff); // HCI handle with PB,BC flag 8 | buf[1] = (char)(((hci_handle >> 8) & 0x0f) | 0x20); 9 | buf[2] = (char)((4 + length) & 0xff); // HCI ACL total data length 10 | buf[3] = (char)((4 + length) >> 8); 11 | buf[4] = (char)(length & 0xff); // L2CAP header: Length 12 | buf[5] = (char)(length >> 8); 13 | buf[6] = 0x01; // L2CAP header: Channel ID 14 | buf[7] = 0x00; // L2CAP Signalling channel over ACL-U logical link 15 | 16 | for (unsigned int i = 0; i < length; i++)//L2CAP C-frame 17 | buf[8 + i] = data[i]; 18 | 19 | Usb.outTransfer(BT_ADDR, ep_record[ DATAOUT_PIPE ].epAddr, (8 + length), buf); 20 | } 21 | void l2cap_connection_response(char rxid, char dcid[], char scid[], byte result) 22 | { 23 | l2capoutbuf[0] = L2CAP_CMD_CONNECTION_RESPONSE;// Code 24 | l2capoutbuf[1] = rxid;// Identifier 25 | l2capoutbuf[2] = 0x08;// Length 26 | l2capoutbuf[3] = 0x00; 27 | l2capoutbuf[4] = dcid[0];// Destination CID 28 | l2capoutbuf[5] = dcid[1]; 29 | l2capoutbuf[6] = scid[0];// Source CID 30 | l2capoutbuf[7] = scid[1]; 31 | l2capoutbuf[8] = result;// Result: Pending or Success 32 | l2capoutbuf[9] = 0x00; 33 | l2capoutbuf[10] = 0x00;//No further information 34 | l2capoutbuf[11] = 0x00; 35 | 36 | L2CAP_Command(l2capoutbuf, 12); 37 | } 38 | void l2cap_config_request(char rxid, char dcid[]) 39 | { 40 | l2capoutbuf[0] = L2CAP_CMD_CONFIG_REQUEST;// Code 41 | l2capoutbuf[1] = rxid;// Identifier 42 | l2capoutbuf[2] = 0x08;// Length 43 | l2capoutbuf[3] = 0x00; 44 | l2capoutbuf[4] = dcid[0];// Destination CID 45 | l2capoutbuf[5] = dcid[1]; 46 | l2capoutbuf[6] = 0x00;// Flags 47 | l2capoutbuf[7] = 0x00; 48 | l2capoutbuf[8] = 0x01;// Config Opt: type = MTU (Maximum Transmission Unit) - Hint 49 | l2capoutbuf[9] = 0x02;// Config Opt: length 50 | l2capoutbuf[10] = 0xFF;// MTU 51 | l2capoutbuf[11] = 0xFF; 52 | 53 | L2CAP_Command(l2capoutbuf, 12); 54 | } 55 | void l2cap_config_response(char rxid, char scid[]) 56 | { 57 | l2capoutbuf[0] = L2CAP_CMD_CONFIG_RESPONSE;// Code 58 | l2capoutbuf[1] = rxid;// Identifier 59 | l2capoutbuf[2] = 0x0A;// Length 60 | l2capoutbuf[3] = 0x00; 61 | l2capoutbuf[4] = scid[0];// Source CID 62 | l2capoutbuf[5] = scid[1]; 63 | l2capoutbuf[6] = 0x00;// Flag 64 | l2capoutbuf[7] = 0x00; 65 | l2capoutbuf[8] = 0x00;// Result 66 | l2capoutbuf[9] = 0x00; 67 | l2capoutbuf[10] = 0x01;// Config 68 | l2capoutbuf[11] = 0x02; 69 | l2capoutbuf[12] = 0xA0; 70 | l2capoutbuf[13] = 0x02; 71 | 72 | L2CAP_Command(l2capoutbuf, 14); 73 | } 74 | void l2cap_disconnection_request(char rxid, char dcid[], char scid[]) 75 | { 76 | l2capoutbuf[0] = L2CAP_CMD_DISCONNECT_REQUEST;// Code 77 | l2capoutbuf[1] = rxid;// Identifier 78 | l2capoutbuf[2] = 0x04;// Length 79 | l2capoutbuf[3] = 0x00; 80 | l2capoutbuf[4] = scid[0];// Really Destination CID 81 | l2capoutbuf[5] = scid[1]; 82 | l2capoutbuf[6] = dcid[0];// Really Source CID 83 | l2capoutbuf[7] = dcid[1]; 84 | L2CAP_Command(l2capoutbuf, 8); 85 | } 86 | void l2cap_disconnection_response(char rxid, char dcid[], char scid[]) 87 | { 88 | l2capoutbuf[0] = L2CAP_CMD_DISCONNECT_RESPONSE;// Code 89 | l2capoutbuf[1] = rxid;// Identifier 90 | l2capoutbuf[2] = 0x04;// Length 91 | l2capoutbuf[3] = 0x00; 92 | l2capoutbuf[4] = scid[0];// Really Destination CID 93 | l2capoutbuf[5] = scid[1]; 94 | l2capoutbuf[6] = dcid[0];// Really Source CID 95 | l2capoutbuf[7] = dcid[1]; 96 | L2CAP_Command(l2capoutbuf, 8); 97 | } 98 | -------------------------------------------------------------------------------- /examples/PS3Bluetooth/PS3Bluetooth.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "enums.h"//Enums to set the LED, Color of the Motions controller etc. 6 | #include "progmemConstants.h" 7 | 8 | /*The application will work in reduced host mode, so we can save program and data 9 | memory space. After verifying the PID and VID we will use known values for the 10 | configuration values for device, interface, endpoints and HID */ 11 | 12 | /* CSR Bluetooth data taken from descriptors */ 13 | #define BT_ADDR 1 14 | #define CSR_VID_LO 0x12 // CSR VID 15 | #define CSR_VID_HI 0x0a 16 | #define CSR_PID_LO 0x01 // Bluetooth HCI Device 17 | #define CSR_PID_HI 0x00 18 | #define BT_CONFIGURATION 1 19 | #define BT_INTERFACE 0 // Only use interface 0 20 | #define BT_NUM_EP 4 // 4 endpoints 21 | #define INT_MAXPKTSIZE 16 22 | #define BULK_MAXPKTSIZE 64 23 | #define EP_INTERRUPT 0x03 // endpoint types 24 | #define EP_BULK 0x02 25 | #define EP_POLL 0x01 // interrupt poll interval 26 | 27 | #define CONTROL_PIPE 0 // names we give to the 4 pipes 28 | #define EVENT_PIPE 1 29 | #define DATAIN_PIPE 2 30 | #define DATAOUT_PIPE 3 31 | 32 | #define MAX_BUFFER_SIZE 64 // size of general purpose data buffer 33 | 34 | /* Bluetooth HCI states for hci_task() */ 35 | #define HCI_INIT_STATE 0 36 | #define HCI_RESET_STATE 1 37 | #define HCI_BUFFER_SIZE_STATE 2 38 | #define HCI_LOCAL_VERSION_STATE 3 39 | #define HCI_LOCAL_NAME_STATE 4 40 | #define HCI_BDADDR_STATE 5 41 | #define HCI_SCANNING_STATE 6 42 | #define HCI_CONNECT_IN_STATE 7 43 | #define HCI_REMOTE_NAME_STATE 8 44 | #define HCI_CONNECTED_STATE 9 45 | #define HCI_DISABLE_SCAN 10 46 | #define HCI_DONE_STATE 11 47 | #define HCI_DISCONNECT_STATE 12 48 | 49 | /* variables used by high level HCI task */ 50 | unsigned char hci_state; //current state of bluetooth hci connection 51 | unsigned int hci_counter; // counter used for bluetooth hci loops 52 | unsigned char remote_name_entry; 53 | 54 | /* HCI event flags*/ 55 | #define HCI_FLAG_CMD_COMPLETE 0x01 56 | #define HCI_FLAG_CMD_STATUS 0x02 57 | #define HCI_FLAG_CONN_COMPLETE 0x04 58 | #define HCI_FLAG_DISCONN_COMPLETE 0x08 59 | #define HCI_FLAG_CONNECT_OK 0x10 60 | #define HCI_FLAG_INQUIRY_COMPLETE 0x20 61 | #define HCI_FLAG_REMOTE_NAME_COMPLETE 0x40 62 | #define HCI_FLAG_INCOMING_REQUEST 0x80 63 | 64 | /*Macros for HCI event flag tests */ 65 | #define hci_cmd_complete (hci_event_flag & HCI_FLAG_CMD_COMPLETE) 66 | #define hci_cmd_status (hci_event_flag & HCI_FLAG_CMD_STATUS) 67 | #define hci_connect_complete (hci_event_flag & HCI_FLAG_CONN_COMPLETE) 68 | #define hci_disconnect_complete (hci_event_flag & HCI_FLAG_DISCONN_COMPLETE) 69 | #define hci_connect_ok (hci_event_flag & HCI_FLAG_CONNECT_OK) 70 | #define hci_inquiry_complete (hci_event_flag & HCI_FLAG_INQUIRY_COMPLETE) 71 | #define hci_remote_name_complete (hci_event_flag & HCI_FLAG_REMOTE_NAME_COMPLETE) 72 | #define hci_incoming_connect_request (hci_event_flag & HCI_FLAG_INCOMING_REQUEST) 73 | unsigned int hci_event_flag;// hci flags of received bluetooth events 74 | 75 | /* HCI Events managed */ 76 | #define EV_COMMAND_COMPLETE 0x0e 77 | #define EV_COMMAND_STATUS 0x0f 78 | #define EV_CONNECT_COMPLETE 0x03 79 | #define EV_DISCONNECT_COMPLETE 0x05 80 | #define EV_NUM_COMPLETE_PKT 0x13 81 | #define EV_INQUIRY_COMPLETE 0x01 82 | #define EV_INQUIRY_RESULT 0x02 83 | #define EV_REMOTE_NAME_COMPLETE 0x07 84 | #define EV_INCOMING_CONNECT 0x04 85 | #define EV_ROLE_CHANGED 0x12 86 | 87 | /*variables filled from HCI event management */ 88 | char hci_command_packets; //how many packets can host send to controller 89 | int hci_handle; 90 | unsigned int acl_outstanding_pkt; 91 | unsigned int acl_data_packet_length; 92 | unsigned char sync_data_packet_length; 93 | unsigned int acl_data_packets; 94 | unsigned int sync_data_packets; 95 | unsigned char hci_version; 96 | unsigned int hci_revision; 97 | unsigned char lmp_version; 98 | unsigned int manufacturer_id; 99 | unsigned int lmp_subversion; 100 | unsigned char my_bdaddr[6]; // bluetooth address stored least significant byte first 101 | unsigned char local_name[20]; // first 20 chars of name 102 | unsigned char disc_bdaddr[3][6]; // maximum of three discovered devices 103 | unsigned char disc_class[3][3]; 104 | unsigned char disc_mode[3]; 105 | unsigned char remote_name[3][30]; // first 20 chars of name 106 | unsigned char dev_link_type; 107 | unsigned char dev_role; 108 | 109 | 110 | /* Bluetooth L2CAP states for L2CAP_task() */ 111 | #define L2CAP_EV_WAIT 0 112 | #define L2CAP_EV_CONTROL_SETUP 1 113 | #define L2CAP_EV_CONTROL_REQUEST 2 114 | #define L2CAP_EV_CONTROL_SUCCESS 3 115 | #define L2CAP_EV_INTERRUPT_SETUP 4 116 | #define L2CAP_EV_INTERRUPT_REQUEST 5 117 | #define L2CAP_EV_INTERRUPT_SUCCESS 6 118 | #define L2CAP_EV_HID_ENABLE_SIXAXIS 7 119 | #define L2CAP_EV_L2CAP_DONE 8 120 | #define L2CAP_EV_INTERRUPT_DISCONNECT 9 121 | #define L2CAP_EV_CONTROL_DISCONNECT 10 122 | unsigned char l2cap_state; 123 | 124 | // Used For Connection Response - Remember to Include High Byte 125 | const byte PENDING = 0x01; 126 | const byte SUCCESSFUL = 0x00; 127 | 128 | /* L2CAP event flags */ 129 | #define L2CAP_EV_CONTROL_CONNECTION_REQUEST 0x01 130 | #define L2CAP_EV_CONTROL_CONFIG_REQUEST 0x02 131 | #define L2CAP_EV_CONTROL_CONFIG_SUCCESS 0x04 132 | 133 | #define L2CAP_EV_INTERRUPT_CONNECTION_REQUEST 0x08 134 | #define L2CAP_EV_INTERRUPT_CONFIG_REQUEST 0x10 135 | #define L2CAP_EV_INTERRUPT_CONFIG_SUCCESS 0x20 136 | 137 | #define L2CAP_EV_CONTROL_DISCONNECT_RESPONSE 0x40 138 | #define L2CAP_EV_INTERRUPT_DISCONNECT_RESPONSE 0x80 139 | 140 | /*Macros for L2CAP event flag tests */ 141 | #define l2cap_control_connection_reguest (l2cap_event_flag & L2CAP_EV_CONTROL_CONNECTION_REQUEST) 142 | #define l2cap_control_config_reguest (l2cap_event_flag & L2CAP_EV_CONTROL_CONFIG_REQUEST) 143 | #define l2cap_control_config_success (l2cap_event_flag & L2CAP_EV_CONTROL_CONFIG_SUCCESS) 144 | 145 | #define l2cap_interrupt_connection_reguest (l2cap_event_flag & L2CAP_EV_INTERRUPT_CONNECTION_REQUEST) 146 | #define l2cap_interrupt_config_reguest (l2cap_event_flag & L2CAP_EV_INTERRUPT_CONFIG_REQUEST) 147 | #define l2cap_interrupt_config_success (l2cap_event_flag & L2CAP_EV_INTERRUPT_CONFIG_SUCCESS) 148 | 149 | #define l2cap_control_disconnect_response (l2cap_event_flag & L2CAP_EV_CONTROL_DISCONNECT_RESPONSE) 150 | #define l2cap_interrupt_disconnect_response (l2cap_event_flag & L2CAP_EV_INTERRUPT_DISCONNECT_RESPONSE) 151 | unsigned int l2cap_event_flag;// l2cap flags of received bluetooth events 152 | 153 | /* L2CAP signaling commands */ 154 | #define L2CAP_CMD_COMMAND_REJECT 0x01 155 | #define L2CAP_CMD_CONNECTION_REQUEST 0x02 156 | #define L2CAP_CMD_CONNECTION_RESPONSE 0x03 157 | #define L2CAP_CMD_CONFIG_REQUEST 0x04 158 | #define L2CAP_CMD_CONFIG_RESPONSE 0x05 159 | #define L2CAP_CMD_DISCONNECT_REQUEST 0x06 160 | #define L2CAP_CMD_DISCONNECT_RESPONSE 0x07 161 | 162 | /* L2CAP Channels */ 163 | char control_scid[2];// L2CAP source CID for HID_Control 164 | char control_dcid[2] = { 165 | 0x40, 0x00 };//0x0040 166 | char interrupt_scid[2];// L2CAP source CID for HID_Interrupt 167 | char interrupt_dcid[2] = { 168 | 0x41, 0x00 };//0x0041 169 | char identifier;//Identifier for connection 170 | 171 | /* Bluetooth L2CAP PSM */ 172 | const char L2CAP_PSM_HID_CTRL = 0x11;// HID_Control 173 | const char L2CAP_PSM_HID_INTR = 0x13;// HID_Interrupt 174 | 175 | boolean PS3BTConnected;// Variable used to indicate if the normal playstation controller is successfully connected 176 | boolean PS3MoveBTConnected;// Variable used to indicate if the move controller is successfully connected 177 | boolean PS3NavigationBTConnected;// Variable used to indicate if the navigation controller is successfully connected 178 | 179 | boolean ButtonChanged;//Indicate if a button has been pressed 180 | unsigned long ButtonState; 181 | unsigned long OldButtonState; 182 | 183 | String outputBT; 184 | String lastOutputBT; 185 | boolean printTemperature; 186 | 187 | unsigned long timerHID;// timer used see if there has to be a delay before a new HID command 188 | unsigned long dtimeHID;// delta time since last HID command 189 | 190 | unsigned long timerBulbRumble;// used to continuously set PS3 Move controller Bulb and rumble values 191 | unsigned long dtimeBulbRumble;// used to know how longs since last since the Bulb and rumble values was written 192 | 193 | EP_RECORD ep_record[ BT_NUM_EP ]; //endpoint record structure for the Bluetooth controller 194 | 195 | char hcibuf[ MAX_BUFFER_SIZE ];//General purpose buffer for hci data 196 | char l2capinbuf[ MAX_BUFFER_SIZE ];//General purpose buffer for l2cap in data 197 | char l2capoutbuf[ MAX_BUFFER_SIZE ];//General purpose buffer for l2cap out data 198 | 199 | char HIDBuffer[ MAX_BUFFER_SIZE ];// Used to store HID commands 200 | #define HIDMoveBufferSize 50 201 | char HIDMoveBuffer[HIDMoveBufferSize];// Used to store HID commands for the Move controller 202 | /* 203 | void setup();//Needed for it to work in earlier version of the Arduino IDE 204 | void loop(); 205 | */ 206 | MAX3421E Max; 207 | USB Usb; 208 | 209 | void setup() { 210 | //Needed for PS3 Dualshock Controller to work 211 | for (int i = 0; i < OUTPUT_REPORT_BUFFER_SIZE; i++) 212 | HIDBuffer[i + 2] = pgm_read_byte(&OUTPUT_REPORT_BUFFER[i]);//First two bytes reserved for report type and ID 213 | 214 | HIDBuffer[0] = 0x52;// HID BT Set_report (0x50) | Report Type (Output 0x02) 215 | HIDBuffer[1] = 0x01;// Report ID 216 | 217 | //Needed for PS3 Move Controller commands to work 218 | HIDMoveBuffer[0] = 0xA2;// HID BT DATA_request (0xA0) | Report Type (Output 0x02) 219 | HIDMoveBuffer[1] = 0x02;// Report ID 220 | 221 | Serial.begin(115200); 222 | Serial.println(""); 223 | printProgStr(Free_Memory_str); 224 | Serial.print(freeMemory()); 225 | Max.powerOn(); 226 | delay(200); 227 | } 228 | 229 | void loop() { 230 | Max.Task(); 231 | Usb.Task(); 232 | delay(1); 233 | if(Usb.getUsbTaskState() == USB_STATE_CONFIGURING)//wait for addressing state 234 | { 235 | CSR_init(); 236 | Usb.setUsbTaskState( USB_STATE_RUNNING ); 237 | } 238 | if(Usb.getUsbTaskState() == USB_STATE_RUNNING) 239 | { 240 | HCI_event_task(); //poll the HCI event pipe 241 | ACL_event_task(); // start polling the ACL input pipe too, though discard data until connected 242 | 243 | if(PS3BTConnected || PS3NavigationBTConnected) 244 | { 245 | outputBT = "";//Reset string 246 | 247 | if(GetAnalogHat(LeftHatX) > 137 || GetAnalogHat(LeftHatX) < 117) 248 | outputBT += String(" - LeftHatX: " + String(GetAnalogHat(LeftHatX), DEC)); 249 | if(GetAnalogHat(LeftHatY) > 137 || GetAnalogHat(LeftHatY) < 117) 250 | outputBT += String(" - LeftHatY: " + String(GetAnalogHat(LeftHatY), DEC)); 251 | if(GetAnalogHat(RightHatX) > 137 || GetAnalogHat(RightHatX) < 117) 252 | outputBT += String(" - RightHatX: " + String(GetAnalogHat(RightHatX), DEC)); 253 | if(GetAnalogHat(RightHatY) > 137 || GetAnalogHat(RightHatY) < 117) 254 | outputBT += String(" - RightHatY: " + String(GetAnalogHat(RightHatY), DEC)); 255 | 256 | //Analog button values can be read from almost all buttons 257 | if(GetAnalogButton(L2_ANALOG) > 0) 258 | outputBT += String(" - L2: " + String(GetAnalogButton(L2_ANALOG), DEC)); 259 | if(GetAnalogButton(R2_ANALOG) > 0) 260 | outputBT += String(" - R2: " + String(GetAnalogButton(R2_ANALOG), DEC)); 261 | 262 | if(ButtonChanged) 263 | { 264 | //Serial.println("ButtonChanged"); 265 | if(GetButton(PS)) 266 | { 267 | outputBT += " - PS"; 268 | disconnectController(); 269 | } 270 | else 271 | { 272 | if(GetButton(TRIANGLE)) 273 | outputBT += " - Traingle"; 274 | if(GetButton(CIRCLE)) 275 | outputBT += " - Circle"; 276 | if(GetButton(CROSS)) 277 | outputBT += " - Cross"; 278 | if(GetButton(SQUARE)) 279 | outputBT += " - Square"; 280 | 281 | if(GetButton(UP)) 282 | outputBT += " - Up"; 283 | if(GetButton(RIGHT)) 284 | outputBT += " - Right"; 285 | if(GetButton(DOWN)) 286 | outputBT += " - Down"; 287 | if(GetButton(LEFT)) 288 | outputBT += " - Left"; 289 | 290 | if(GetButton(L1)) 291 | outputBT += " - L1"; 292 | //if(GetButton(L2)) 293 | // outputBT += " - L2"; 294 | if(GetButton(L3)) 295 | outputBT += " - L3"; 296 | if(GetButton(R1)) 297 | outputBT += " - R1"; 298 | //if(GetButton(R2)) 299 | // outputBT += " - R2"; 300 | if(GetButton(R3)) 301 | outputBT += " - R3"; 302 | 303 | if(GetButton(SELECT)) 304 | outputBT += " - Select - " + GetStatusString(); 305 | if(GetButton(START)) 306 | outputBT += " - Start"; 307 | } 308 | } 309 | if (outputBT != "" && outputBT != lastOutputBT)//Check if output is not empty and not equal to the last one 310 | Serial.print("\r\nPS3 Controller" + outputBT); 311 | lastOutputBT = outputBT; 312 | } 313 | else if(PS3MoveBTConnected) 314 | { 315 | outputBT = "";//Reset string 316 | 317 | if(GetAnalogButton(T_MOVE_ANALOG) > 0) 318 | outputBT += String(" - T: " + String(GetAnalogButton(T_MOVE_ANALOG), DEC)); 319 | 320 | if(ButtonChanged) 321 | { 322 | //Serial.println("ButtonChanged"); 323 | if(GetButton(PS_MOVE)) 324 | { 325 | outputBT += " - PS"; 326 | disconnectController(); 327 | } 328 | else 329 | { 330 | if (GetButton(SELECT_MOVE)) 331 | { 332 | outputBT += " - Select"; 333 | printTemperature = false; 334 | } 335 | if (GetButton(START_MOVE)) 336 | { 337 | outputBT += " - Start"; 338 | printTemperature = true; 339 | } 340 | 341 | if (GetButton(TRIANGLE_MOVE)) 342 | { 343 | outputBT += " - Triangle"; 344 | hid_MoveSetBulb(Red); 345 | } 346 | if (GetButton(CIRCLE_MOVE)) 347 | { 348 | outputBT += " - Circle"; 349 | hid_MoveSetBulb(Green); 350 | } 351 | if (GetButton(SQUARE_MOVE)) 352 | { 353 | outputBT += " - Square"; 354 | hid_MoveSetBulb(Blue); 355 | } 356 | if (GetButton(CROSS_MOVE)) 357 | { 358 | outputBT += " - Cross"; 359 | hid_MoveSetBulb(Yellow); 360 | } 361 | 362 | if (GetButton(MOVE_MOVE)) 363 | { 364 | hid_MoveSetBulb(Off); 365 | outputBT += " - Move"; 366 | outputBT += " - " + GetStatusString();//Print status string 367 | } 368 | //if (GetButton(T_MOVE)) 369 | //outputBT += " - T"; 370 | } 371 | } 372 | if(printTemperature) 373 | { 374 | String templow; 375 | String temphigh; 376 | String input = String(GetSensor(tempMove), DEC); 377 | 378 | if (input.length() > 3) 379 | { 380 | temphigh = input.substring(0, 2); 381 | templow = input.substring(2); 382 | } 383 | else 384 | { 385 | temphigh = input.substring(0, 1); 386 | templow = input.substring(1); 387 | } 388 | outputBT += " - Temperature: " + temphigh + "." + templow; 389 | } 390 | if (outputBT != "" && outputBT != lastOutputBT)//Check if output is not empty and not equal to the last one 391 | Serial.print("\r\nPS3 Move Controller" + outputBT); 392 | lastOutputBT = outputBT; 393 | } 394 | } 395 | } 396 | /* Initialize CSR Bluetooth Controller */ 397 | void CSR_init( void ) 398 | { 399 | byte rcode = 0; //return code 400 | /* Initialize data structures for endpoints of device 1*/ 401 | ep_record[ CONTROL_PIPE ] = *( Usb.getDevTableEntry( 0,0 )); //copy endpoint 0 parameters 402 | ep_record[ EVENT_PIPE ].epAddr = 0x01; // Bluetooth event endpoint 403 | ep_record[ EVENT_PIPE ].Attr = EP_INTERRUPT; 404 | ep_record[ EVENT_PIPE ].MaxPktSize = INT_MAXPKTSIZE; 405 | ep_record[ EVENT_PIPE ].Interval = EP_POLL; 406 | ep_record[ EVENT_PIPE ].sndToggle = bmSNDTOG0; 407 | ep_record[ EVENT_PIPE ].rcvToggle = bmRCVTOG0; 408 | ep_record[ DATAIN_PIPE ].epAddr = 0x02; // Bluetoth data endpoint 409 | ep_record[ DATAIN_PIPE ].Attr = EP_BULK; 410 | ep_record[ DATAIN_PIPE ].MaxPktSize = BULK_MAXPKTSIZE; 411 | ep_record[ DATAIN_PIPE ].Interval = 0; 412 | ep_record[ DATAIN_PIPE ].sndToggle = bmSNDTOG0; 413 | ep_record[ DATAIN_PIPE ].rcvToggle = bmRCVTOG0; 414 | ep_record[ DATAOUT_PIPE ].epAddr = 0x02; // Bluetooth data endpoint 415 | ep_record[ DATAOUT_PIPE ].Attr = EP_BULK; 416 | ep_record[ DATAOUT_PIPE ].MaxPktSize = BULK_MAXPKTSIZE; 417 | ep_record[ DATAOUT_PIPE ].Interval = 0; 418 | ep_record[ DATAOUT_PIPE ].sndToggle = bmSNDTOG0; 419 | ep_record[ DATAOUT_PIPE ].rcvToggle = bmRCVTOG0; 420 | Usb.setDevTableEntry( BT_ADDR, ep_record ); //plug kbd.endpoint parameters to devtable 421 | 422 | /* read the device descriptor and check VID and PID*/ 423 | rcode = Usb.getDevDescr( BT_ADDR, ep_record[ CONTROL_PIPE ].epAddr, DEV_DESCR_LEN , hcibuf ); 424 | if( rcode ) { 425 | printProgStr(Dev_Error_str); 426 | Serial.print( rcode, HEX ); 427 | while(1); //stop 428 | } 429 | if((hcibuf[ 8 ] != CSR_VID_LO) || (hcibuf[ 9 ] != CSR_VID_HI) || (hcibuf[ 10 ] != CSR_PID_LO) || (hcibuf[ 11 ] != CSR_PID_HI) ) { 430 | printProgStr(Wrong_Device_str); 431 | while(1); //stop 432 | } 433 | 434 | /* Configure device */ 435 | rcode = Usb.setConf( BT_ADDR, ep_record[ CONTROL_PIPE ].epAddr, BT_CONFIGURATION ); 436 | if( rcode ) { 437 | printProgStr(Config_Error_str); 438 | Serial.print( rcode, HEX ); 439 | while(1); //stop 440 | } 441 | 442 | 443 | hci_state = HCI_INIT_STATE; 444 | hci_counter = 0; 445 | 446 | l2cap_state = L2CAP_EV_WAIT; 447 | 448 | printProgStr(CSR_Init_str); 449 | delay(200); 450 | } 451 | 452 | // Print a string from Program Memory directly to save RAM 453 | void printProgStr(const prog_char str[]) 454 | { 455 | char c; 456 | if(!str) 457 | return; 458 | while((c = pgm_read_byte(str++))) 459 | Serial.print(c); 460 | } 461 | /* 462 | void test() 463 | { 464 | for(int i = 0; i < OUTPUT_REPORT_BUFFER_SIZE;i++) 465 | { 466 | Serial.print(" 0x"); 467 | Serial.print(pgm_read_byte(&OUTPUT_REPORT_BUFFER[i]), HEX); 468 | } 469 | } 470 | */ 471 | void disconnectController()//Use this void to disconnect any of the controllers 472 | { 473 | if (PS3BTConnected) 474 | PS3BTConnected = false; 475 | else if (PS3MoveBTConnected) 476 | PS3MoveBTConnected = false; 477 | else if (PS3NavigationBTConnected) 478 | PS3NavigationBTConnected = false; 479 | 480 | //First the HID interrupt channel has to be disconencted, then the HID control channel and finally the HCI connection 481 | l2cap_disconnection_request(0x0A, interrupt_dcid, interrupt_scid); 482 | l2cap_state = L2CAP_EV_INTERRUPT_DISCONNECT; 483 | } 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | -------------------------------------------------------------------------------- /examples/PS3Bluetooth/ReadControllerCommands.ino: -------------------------------------------------------------------------------- 1 | boolean GetButton(Button b) 2 | { 3 | if (l2capinbuf == NULL) 4 | return false; 5 | if (((unsigned char)l2capinbuf[(unsigned int)b >> 8] & ((byte)b & 0xff)) > 0) 6 | return true; 7 | else 8 | return false; 9 | } 10 | byte GetAnalogButton(AnalogButton a) 11 | { 12 | if (l2capinbuf == NULL) 13 | return 0; 14 | return (byte)((unsigned char)l2capinbuf[(unsigned int)a]); 15 | } 16 | byte GetAnalogHat(AnalogHat a) 17 | { 18 | if (l2capinbuf == NULL) 19 | return 0; 20 | return (byte)((unsigned char)l2capinbuf[(unsigned int)a]); 21 | } 22 | long GetSensor(Sensor a) 23 | { 24 | if (a == aX || a == aY || a == aZ || a == gZ) 25 | { 26 | if (l2capinbuf == NULL) 27 | return 0; 28 | return (((unsigned char)l2capinbuf[(unsigned int)a] << 8) | (unsigned char)l2capinbuf[(unsigned int)a + 1]); 29 | } 30 | else if (a == mXmove || a == mYmove || a == mZmove) 31 | { 32 | //Might not be correct, haven't tested it yet 33 | if (l2capinbuf == NULL) 34 | return 0; 35 | if (a == mXmove) 36 | return (((unsigned char)l2capinbuf[(unsigned int)a + 1] << 0x04) | ((unsigned char)l2capinbuf[(unsigned int)a] << 0x0C)); 37 | //return (((unsigned char)l2capinbuf[(unsigned int)a + 1]) | (((unsigned char)l2capinbuf[(unsigned int)a] & 0x0F)) << 8); 38 | else if (a == mYmove) 39 | return (((unsigned char)l2capinbuf[(unsigned int)a + 1] & 0xF0) | ((unsigned char)l2capinbuf[(unsigned int)a] << 0x08)); 40 | //return (((unsigned char)l2capinbuf[(unsigned int)a + 1]) | (((unsigned char)l2capinbuf[(unsigned int)a] & 0x0F)) << 8); 41 | else if (a == mZmove) 42 | return (((unsigned char)l2capinbuf[(unsigned int)a + 1] << 0x0F) | ((unsigned char)l2capinbuf[(unsigned int)a] << 0x0C)); 43 | //return ((((unsigned char)l2capinbuf[(unsigned int)a + 1] & 0xF0) >> 4) | ((unsigned char)l2capinbuf[(unsigned int)a] << 4)); 44 | else 45 | return 0; 46 | } 47 | else if (a == tempMove) 48 | { 49 | if (l2capinbuf == NULL) 50 | return 0; 51 | return ((((unsigned char)l2capinbuf[(unsigned int)a + 1] & 0xF0) >> 4) | ((unsigned char)l2capinbuf[(unsigned int)a] << 4)); 52 | } 53 | else 54 | { 55 | if (l2capinbuf == NULL) 56 | return 0; 57 | return ((((unsigned char)l2capinbuf[(unsigned int)a + 1] << 8) | (unsigned char)l2capinbuf[(unsigned int)a]) - 0x8000); 58 | } 59 | } 60 | short GetAngle(Angle a, boolean resolution)//Boolean indicate if 360-degrees resolution is used or not - set false if you want to use both axis 61 | { 62 | double accXin; 63 | double accXval; 64 | double Pitch; 65 | 66 | double accYin; 67 | double accYval; 68 | double Roll; 69 | 70 | double accZin; 71 | double accZval; 72 | 73 | //Data for the Kionix KXPC4 used in DualShock 3 74 | double sensivity = 204.6;//0.66/3.3*1023 (660mV/g) 75 | double zeroG = 511.5;//1.65/3.3*1023 (1,65V) 76 | double R;//force vector 77 | 78 | accXin = GetSensor(aX); 79 | accXval = (zeroG - accXin) / sensivity;//Convert to g's 80 | accXval *= 2; 81 | 82 | accYin = GetSensor(aY); 83 | accYval = (zeroG - accYin) / sensivity;//Convert to g's 84 | accYval *= 2; 85 | 86 | accZin = GetSensor(aZ); 87 | accZval = (zeroG - accZin) / sensivity;//Convert to g's 88 | accZval *= 2; 89 | 90 | //Debug.Print("accXin: " + accXin + " accYin: " + accYin + " accZin: " + accZin); 91 | //Debug.Print("aX: " + accXval + " aY: " + accYval + " aZ: " + accZval); 92 | 93 | R = sqrt(pow(accXval, 2) + pow(accYval, 2) + pow(accZval, 2)); 94 | 95 | if (a == Pitch) 96 | { 97 | //the result will come out as radians, so it is multiplied by 180/pi, to convert to degrees 98 | //In the end it is minus by 90, so its 0 degrees when in horizontal postion 99 | Pitch = acos(accXval / R) * 180 / PI - 90; 100 | //Debug.Print("accXangle: " + accXangle); 101 | 102 | if(resolution) 103 | { 104 | if (accZval < 0)//Convert to 360 degrees resolution - uncomment if you need both pitch and roll 105 | { 106 | if (Pitch < 0) 107 | Pitch = -180 - Pitch; 108 | else 109 | Pitch = 180 - Pitch; 110 | } 111 | } 112 | return (short)Pitch; 113 | 114 | } 115 | else 116 | { 117 | //the result will come out as radians, so it is multiplied by 180/pi, to convert to degrees 118 | //In the end it is minus by 90, so its 0 degrees when in horizontal postion 119 | Roll = acos(accYval / R) * 180 / PI - 90; 120 | //Debug.Print("accYangle: " + accYangle); 121 | 122 | if(resolution) 123 | { 124 | if (accZval < 0)//Convert to 360 degrees resolution - uncomment if you need both pitch and roll 125 | { 126 | if (Roll < 0) 127 | Roll = -180 - Roll; 128 | else 129 | Roll = 180 - Roll; 130 | } 131 | } 132 | return (short)Roll; 133 | } 134 | } 135 | boolean GetStatus(Status c) 136 | { 137 | if (l2capinbuf == NULL) 138 | return false; 139 | if ((unsigned char)l2capinbuf[(unsigned int)c >> 8] == ((char)c & 0xff)) 140 | return true; 141 | return false; 142 | } 143 | String GetStatusString() 144 | { 145 | if (!PS3MoveBTConnected) 146 | { 147 | String ConnectionStatus = ""; 148 | if (GetStatus(Plugged)) ConnectionStatus = "Plugged"; 149 | else if (GetStatus(Unplugged)) ConnectionStatus = "Unplugged"; 150 | else ConnectionStatus = "Error"; 151 | 152 | String PowerRating = ""; 153 | if (GetStatus(Charging)) PowerRating = "Charging"; 154 | else if (GetStatus(NotCharging)) PowerRating = "Not Charging"; 155 | else if (GetStatus(Shutdown)) PowerRating = "Shutdown"; 156 | else if (GetStatus(Dying)) PowerRating = "Dying"; 157 | else if (GetStatus(Low)) PowerRating = "Low"; 158 | else if (GetStatus(High)) PowerRating = "High"; 159 | else if (GetStatus(Full)) PowerRating = "Full"; 160 | else PowerRating = "Error: " + (unsigned char)l2capinbuf[39]; 161 | 162 | String WirelessStatus = ""; 163 | if (GetStatus(CableRumble)) WirelessStatus = "Cable - Rumble is on"; 164 | else if (GetStatus(Cable)) WirelessStatus = "Cable - Rumble is off"; 165 | else if (GetStatus(BluetoothRumble)) WirelessStatus = "Bluetooth - Rumble is on"; 166 | else if (GetStatus(Bluetooth)) WirelessStatus = "Bluetooth - Rumble is off"; 167 | else WirelessStatus = "Error"; 168 | 169 | return ("ConnectionStatus: " + ConnectionStatus + " - PowerRating: " + PowerRating + " - WirelessStatus: " + WirelessStatus); 170 | } 171 | else 172 | { 173 | String PowerRating = ""; 174 | if (GetStatus(MoveCharging)) PowerRating = "Charging"; 175 | else if (GetStatus(MoveNotCharging)) PowerRating = "Not Charging"; 176 | else if (GetStatus(MoveShutdown)) PowerRating = "Shutdown"; 177 | else if (GetStatus(MoveDying)) PowerRating = "Dying"; 178 | else if (GetStatus(MoveLow)) PowerRating = "Low"; 179 | else if (GetStatus(MoveHigh)) PowerRating = "High"; 180 | else if (GetStatus(MoveFull)) PowerRating = "Full"; 181 | else PowerRating = "Error: " + (unsigned char)l2capinbuf[21]; 182 | 183 | return ("PowerRating: " + PowerRating); 184 | } 185 | } 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /examples/PS3Bluetooth/enums.h: -------------------------------------------------------------------------------- 1 | enum LED 2 | { 3 | LED1 = 0x01, 4 | LED2 = 0x02, 5 | LED3 = 0x04, 6 | LED4 = 0x08, 7 | 8 | LED5 = 0x09, 9 | LED6 = 0x0A, 10 | LED7 = 0x0C, 11 | LED8 = 0x0D, 12 | LED9 = 0x0E, 13 | LED10 = 0x0F, 14 | }; 15 | enum Colors 16 | { 17 | //Used to set the colors of the move controller 18 | Red = 0xFF0000,//((255 << 16) | (0 << 8) | 0); 19 | Green = 0xFF00,//((0 << 16) | (255 << 8) | 0); 20 | Blue = 0xFF,//((0 << 16) | (0 << 8) | 255); 21 | 22 | Yellow = 0xFFEB04,//((255 << 16) | (235 << 8) | 4); 23 | Lightblue = 0xFFFF,//((0 << 16) | (255 << 8) | 255); 24 | Purble = 0xFF00FF,//((255 << 16) | (0 << 8) | 255); 25 | 26 | White = 0xFFFFFF,//((255 << 16) | (255 << 8) | 255); 27 | Off = 0x00,//((0 << 16) | (0 << 8) | 0); 28 | }; 29 | 30 | enum Button 31 | { 32 | // byte location | bit location 33 | 34 | //Sixaxis Dualshcock 3 & Navigation controller 35 | SELECT = (11 << 8) | 0x01, 36 | L3 = (11 << 8) | 0x02, 37 | R3 = (11 << 8) | 0x04, 38 | START = (11 << 8) | 0x08, 39 | UP = (11 << 8) | 0x10, 40 | RIGHT = (11 << 8) | 0x20, 41 | DOWN = (11 << 8) | 0x40, 42 | LEFT = (11 << 8) | 0x80, 43 | 44 | L2 = (12 << 8) | 0x01, 45 | R2 = (12 << 8) | 0x02, 46 | L1 = (12 << 8) | 0x04, 47 | R1 = (12 << 8) | 0x08, 48 | TRIANGLE = (12 << 8) | 0x10, 49 | CIRCLE = (12 << 8) | 0x20, 50 | CROSS = (12 << 8) | 0x40, 51 | SQUARE = (12 << 8) | 0x80, 52 | 53 | PS = (13 << 8) | 0x01, 54 | 55 | //Playstation Move Controller 56 | SELECT_MOVE = (10 << 8) | 0x01, 57 | START_MOVE = (10 << 8) | 0x08, 58 | 59 | TRIANGLE_MOVE = (11 << 8) | 0x10, 60 | CIRCLE_MOVE = (11 << 8) | 0x20, 61 | CROSS_MOVE = (11 << 8) | 0x40, 62 | SQUARE_MOVE = (11 << 8) | 0x80, 63 | 64 | PS_MOVE = (12 << 8) | 0x01, 65 | MOVE_MOVE = (12 << 8) | 0x08,//covers 12 bits - we only need to read the top 8 66 | T_MOVE = (12 << 8) | 0x10,//covers 12 bits - we only need to read the top 8 67 | }; 68 | enum AnalogButton 69 | { 70 | //Sixaxis Dualshcock 3 & Navigation controller 71 | UP_ANALOG = 23, 72 | RIGHT_ANALOG = 24, 73 | DOWN_ANALOG = 25, 74 | LEFT_ANALOG = 26, 75 | 76 | L2_ANALOG = 27, 77 | R2_ANALOG = 28, 78 | L1_ANALOG = 29, 79 | R1_ANALOG = 30, 80 | TRIANGLE_ANALOG = 31, 81 | CIRCLE_ANALOG = 32, 82 | CROSS_ANALOG = 33, 83 | SQUARE_ANALOG = 34, 84 | 85 | //Playstation Move Controller 86 | T_MOVE_ANALOG = 15,//Both at byte 14 (last reading) and byte 15 (current reading) 87 | }; 88 | enum AnalogHat 89 | { 90 | LeftHatX = 15, 91 | LeftHatY = 16, 92 | RightHatX = 17, 93 | RightHatY = 18, 94 | }; 95 | enum Sensor 96 | { 97 | //Sensors inside the Sixaxis Dualshock 3 controller 98 | aX = 50, 99 | aY = 52, 100 | aZ = 54, 101 | gZ = 56, 102 | 103 | //Sensors inside the move motion controller - it only reads the 2nd frame 104 | aXmove = 28, 105 | aZmove = 30, 106 | aYmove = 32, 107 | 108 | gXmove = 40, 109 | gZmove = 42, 110 | gYmove = 44, 111 | 112 | tempMove = 46, 113 | 114 | mXmove = 47, 115 | mZmove = 49, 116 | mYmove = 50, 117 | }; 118 | enum Angle 119 | { 120 | Pitch = 0x01, 121 | Roll = 0x02, 122 | }; 123 | enum Status 124 | { 125 | // byte location | bit location 126 | Plugged = (38 << 8) | 0x02, 127 | Unplugged = (38 << 8) | 0x03, 128 | 129 | Charging = (39 << 8) | 0xEE, 130 | NotCharging = (39 << 8) | 0xF1, 131 | Shutdown = (39 << 8) | 0x01, 132 | Dying = (39 << 8) | 0x02, 133 | Low = (39 << 8) | 0x03, 134 | High = (39 << 8) | 0x04, 135 | Full = (39 << 8) | 0x05, 136 | 137 | MoveCharging = (21 << 8) | 0xEE, 138 | MoveNotCharging = (21 << 8) | 0xF1, 139 | MoveShutdown = (21 << 8) | 0x01, 140 | MoveDying = (21 << 8) | 0x02, 141 | MoveLow = (21 << 8) | 0x03, 142 | MoveHigh = (21 << 8) | 0x04, 143 | MoveFull = (21 << 8) | 0x05, 144 | 145 | CableRumble = (40 << 8) | 0x10,//Opperating by USB and rumble is turned on 146 | Cable = (40 << 8) | 0x12,//Opperating by USB and rumble is turned off 147 | BluetoothRumble = (40 << 8) | 0x14,//Opperating by bluetooth and rumble is turned on 148 | Bluetooth = (40 << 8) | 0x16,//Opperating by bluetooth and rumble is turned off 149 | }; 150 | enum Rumble 151 | { 152 | RumbleHigh = 0x10, 153 | RumbleLow = 0x20, 154 | }; 155 | 156 | -------------------------------------------------------------------------------- /examples/PS3Bluetooth/progmemConstants.h: -------------------------------------------------------------------------------- 1 | #define OUTPUT_REPORT_BUFFER_SIZE 48 2 | 3 | const byte OUTPUT_REPORT_BUFFER[OUTPUT_REPORT_BUFFER_SIZE] PROGMEM = 4 | { 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0xff, 0x27, 0x10, 0x00, 0x32, 8 | 0xff, 0x27, 0x10, 0x00, 0x32, 9 | 0xff, 0x27, 0x10, 0x00, 0x32, 10 | 0xff, 0x27, 0x10, 0x00, 0x32, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 14 | }; 15 | /* Print strings in Program Memory */ 16 | /* HCI Strings */ 17 | const char Free_Memory_str[] PROGMEM = "\r\nfreeMemory() reports: "; 18 | const char Dev_Error_str[] PROGMEM ="\r\nDevice Descriptor Error: "; 19 | const char Wrong_Device_str[] PROGMEM ="\r\nWrong USB Device ID"; 20 | const char Config_Error_str[] PROGMEM ="\r\nError Setting Configuration: "; 21 | const char Int_Error_str[] PROGMEM ="\r\nError Setting Interface: "; 22 | const char CSR_Init_str[] PROGMEM ="\r\nCSR Initialized"; 23 | const char HCI_Reset_str[] PROGMEM ="\r\nHCI Reset complete"; 24 | const char Reset_Error_str[] PROGMEM ="\r\nNo response to HCI Reset "; 25 | const char ACL_Length_str[] PROGMEM ="\r\nACL Data Packet Length: "; 26 | const char SCO_Length_str[] PROGMEM ="\r\nSCO Data Packet Length: "; 27 | const char ACL_Number_str[] PROGMEM ="\r\nTotal ACL Data Packets: "; 28 | const char SCO_Number_str[] PROGMEM ="\r\nTotal SCO Data Packets: "; 29 | const char HCI_Version_str[] PROGMEM ="\r\nHCI Version: "; 30 | const char HCI_Revision_str[] PROGMEM ="\r\nHCI Revision: "; 31 | const char LMP_Version_str[] PROGMEM ="\r\nLMP Version: "; 32 | const char Manuf_Id_str[] PROGMEM ="\r\nManufacturer Id: "; 33 | const char LMP_Subvers_str[] PROGMEM ="\r\nLMP Subversion: "; 34 | const char Local_Name_str[] PROGMEM ="\r\nLocal Name: "; 35 | const char Local_BDADDR_str[] PROGMEM ="\r\nLocal Bluetooth Address: "; 36 | const char Class_str[] PROGMEM =" Class: "; 37 | const char Mode_str[] PROGMEM =" Mode: "; 38 | const char Connect_In_str[] PROGMEM = "\r\nWait For Incoming Connection Request"; 39 | const char In_Request_str[] PROGMEM = "\r\nIncoming Request"; 40 | const char Remote_Name_str[] PROGMEM ="\r\nRemote Name: "; 41 | const char Device_Connected_str[] PROGMEM = "\r\nConnected to Device: "; 42 | const char Device_Disconnected_str[] PROGMEM = "\r\nDisconnected from Device: "; 43 | const char Scan_Disabled_str[] PROGMEM = "\r\nScan Disabled"; 44 | const char HCI_Command_Failed_str[] PROGMEM ="\r\nHCI Command Failed: "; 45 | const char Unmanaged_Event_str[] PROGMEM ="\r\nUnmanaged Event: "; 46 | 47 | /* L2CAP Strings */ 48 | const char Cmd_Reject_str[] PROGMEM ="\r\nL2CAP Command Rejected - Reason: "; 49 | const char Disconnet_Req_Control_str[] PROGMEM ="\r\nDisconnected Request: Disconnected Control"; 50 | const char Disconnet_Req_Interrupt_str[] PROGMEM ="\r\nDisconnected Request: Disconnected Interrupt"; 51 | const char HID_Control_Connect_Req_str[] PROGMEM ="\r\nHID Control Incoming Connection Request"; 52 | const char HID_Control_Config_Req_str[] PROGMEM ="\r\nHID Control Configuration Request"; 53 | const char HID_Control_Success_str[] PROGMEM ="\r\nHID Control Successfully Configured"; 54 | const char HID_Interrupt_Connect_Req_str[] PROGMEM ="\r\nHID Interrupt Incoming Connection Request"; 55 | const char HID_Interrupt_Config_Req_str[] PROGMEM ="\r\nHID Interrupt Configuration Request"; 56 | const char HID_Interrupt_Success_str[] PROGMEM ="\r\nHID Interrupt Successfully Configured"; 57 | const char Dualshock_Enabled_str[] PROGMEM ="\r\nDualshock 3 Controller Enabled"; 58 | const char Navigation_Enabled_str[] PROGMEM ="\r\nNavigation Controller Enabled"; 59 | const char Motion_Enabled_str[] PROGMEM ="\r\nMotion Controller Enabled"; 60 | const char Interrupt_Disconnected_str[] PROGMEM ="\r\nDisconnected Interrupt Channel"; 61 | const char Control_Disconnected_str[] PROGMEM ="\r\nDisconnected Control Channel"; 62 | -------------------------------------------------------------------------------- /examples/PS3Pair/PS3Pair.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | unsigned char BDADDR[6] = { 0x00, 0x1F, 0x81, 0x00, 0x08, 0x30 }; 4 | 5 | PS3_USB PS3;// create an object for the PS3 Game Controller 6 | 7 | void setup() 8 | { 9 | Serial.begin(115200); 10 | Serial.println("\r\nConnect a PS3 Controller to change the bluetooth address"); 11 | PS3.init(); 12 | } 13 | 14 | void loop() 15 | { 16 | PS3.task();// perform the regular USB routines 17 | 18 | if (PS3.statConnected())// report received ? 19 | { 20 | if(PS3.MoveConnected()) 21 | PS3.setMoveBDADDR(BDADDR); 22 | else 23 | PS3.setBDADDR(BDADDR); 24 | printBDADDR(BDADDR); 25 | while(1); 26 | } 27 | } 28 | 29 | void printBDADDR(unsigned char* bdaddr) 30 | { 31 | Serial.print("The bluetooth address was set to: "); 32 | 33 | for(int i=0;i<5;i++) 34 | { 35 | if(bdaddr[i] < 16) 36 | Serial.print("0"); 37 | Serial.print(bdaddr[i], HEX); 38 | Serial.print(":"); 39 | } 40 | if(bdaddr[5] < 16) 41 | Serial.print("0"); 42 | Serial.println(bdaddr[5], HEX); 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /gpl-3.0.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /ps3_usb.cpp: -------------------------------------------------------------------------------- 1 | /* ps3_usb.cpp - PS3 Game Controller on Arduino USB Host Library 2 | 3 | Copyright (c) 2009 Richard Ibbotson richard.ibbotson@btinternet.com 4 | 5 | All right reserved. This library is free software; you can redistribute it 6 | and/or modify it under the terms of the GNU Lesser General Public License 7 | as published by the Free Software Foundation; either version 2.1 of the License, 8 | or (at your option) any later version. 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | You should have received a copy of the GNU Lesser General Public License along 14 | with this library; if not, write to the Free Software Foundation, Inc., 15 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 16 | 17 | #include "ps3_usb.h" 18 | 19 | static unsigned char ps3_status; 20 | static unsigned int oldbuttonstate; 21 | static unsigned char oldpsbuttonstate; 22 | bool MoveController; 23 | 24 | prog_char output_01_report[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x02, 0xff, 0x27, 0x10, 0x00, 0x32, 0xff, 26 | 0x27, 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00, 27 | 0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 30 | }; 31 | 32 | prog_char feature_F4_report[] PROGMEM = {0x42, 0x0c, 0x00, 0x00}; 33 | 34 | EP_RECORD ep_recordPS3USB[ PS3_NUM_EP ]; //endpoint record structure for the PS3 controller 35 | TYPE_01_REPORT report; 36 | 37 | MAX3421E MaxPS3; 38 | USB UsbPS3; 39 | 40 | /* constructor */ 41 | 42 | PS3_USB::PS3_USB() { 43 | 44 | } 45 | 46 | void PS3_USB::init(void){ 47 | MaxPS3.powerOn(); 48 | delay(200); 49 | } 50 | 51 | void PS3_USB::task(void){ 52 | MaxPS3.Task(); 53 | UsbPS3.Task(); 54 | 55 | if( UsbPS3.getUsbTaskState() == USB_DETACHED_SUBSTATE_INITIALIZE) { //reinitialised 56 | ps3_status = 0; 57 | 58 | } 59 | 60 | 61 | if( UsbPS3.getUsbTaskState() == USB_STATE_CONFIGURING ) { //wait for addressing state 62 | 63 | PS3_init(); 64 | if( ps3_status & statusPS3Connected) UsbPS3.setUsbTaskState( USB_STATE_RUNNING ); 65 | } 66 | if( UsbPS3.getUsbTaskState() == USB_STATE_RUNNING ) { //poll the PS3 Controller 67 | PS3_poll(); 68 | } 69 | 70 | 71 | } 72 | 73 | /* Initialize PS3 Controller */ 74 | void PS3_USB::PS3_init( void ) 75 | { 76 | byte rcode = 0; //return code 77 | char buf[ 64 ] = { 0 }; //General purpose buffer for usb data 78 | byte i; 79 | USB_DEVICE_DESCRIPTOR* device_descriptor; 80 | 81 | ps3_status = statusDeviceConnected;; 82 | 83 | 84 | 85 | /* Initialize data structures for endpoints of device */ 86 | ep_recordPS3USB[ CONTROL_PIPE ] = *( UsbPS3.getDevTableEntry( 0,0 )); //copy endpoint 0 parameters 87 | ep_recordPS3USB[ OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint 88 | ep_recordPS3USB[ OUTPUT_PIPE ].Attr = EP_INTERRUPT; 89 | ep_recordPS3USB[ OUTPUT_PIPE ].MaxPktSize = EP_MAXPKTSIZE; 90 | ep_recordPS3USB[ OUTPUT_PIPE ].Interval = EP_POLL; 91 | ep_recordPS3USB[ OUTPUT_PIPE ].sndToggle = bmSNDTOG0; 92 | ep_recordPS3USB[ OUTPUT_PIPE ].rcvToggle = bmRCVTOG0; 93 | ep_recordPS3USB[ INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint 94 | ep_recordPS3USB[ INPUT_PIPE ].Attr = EP_INTERRUPT; 95 | ep_recordPS3USB[ INPUT_PIPE ].MaxPktSize = EP_MAXPKTSIZE; 96 | ep_recordPS3USB[ INPUT_PIPE ].Interval = EP_POLL; 97 | ep_recordPS3USB[ INPUT_PIPE ].sndToggle = bmSNDTOG0; 98 | ep_recordPS3USB[ INPUT_PIPE ].rcvToggle = bmRCVTOG0; 99 | 100 | UsbPS3.setDevTableEntry( PS3_ADDR, ep_recordPS3USB ); //plug kbd.endpoint parameters to devtable 101 | delay(200); // give time for address change 102 | 103 | /* read the device descriptor and check VID and PID*/ 104 | rcode = UsbPS3.getDevDescr( PS3_ADDR, ep_recordPS3USB[ CONTROL_PIPE ].epAddr, DEV_DESCR_LEN , buf ); 105 | if( rcode ) return; 106 | device_descriptor = (USB_DEVICE_DESCRIPTOR *) &buf; 107 | 108 | if((device_descriptor->idVendor == PS3_VID || device_descriptor->idVendor == PS3NAVIGATION_VID) && (device_descriptor->idProduct == PS3_PID || device_descriptor->idProduct == PS3NAVIGATION_PID)) 109 | { 110 | /* Configure device */ 111 | rcode = UsbPS3.setConf( PS3_ADDR, ep_recordPS3USB[ CONTROL_PIPE ].epAddr, PS3_CONFIGURATION ); 112 | if( rcode ) return; 113 | ps3_status |= statusUSBConfigured; 114 | 115 | /* Set the PS3 controller to send reports */ 116 | for (i=0; i < PS3_F4_REPORT_LEN; i++) buf[i] = pgm_read_byte_near( feature_F4_report + i); 117 | rcode = UsbPS3.setReport( PS3_ADDR, ep_recordPS3USB[ CONTROL_PIPE ].epAddr, PS3_F4_REPORT_LEN, PS3_IF, HID_REPORT_FEATURE, PS3_F4_REPORT_ID , buf ); 118 | if( rcode ) return; 119 | 120 | /* Set the PS3 controller LED 1 On */ 121 | for (i=0; i < PS3_01_REPORT_LEN; i++) buf[i] = pgm_read_byte_near( output_01_report + i); 122 | rcode = UsbPS3.setReport( PS3_ADDR, ep_recordPS3USB[ CONTROL_PIPE ].epAddr, PS3_01_REPORT_LEN, PS3_IF, HID_REPORT_OUTPUT, PS3_01_REPORT_ID , buf ); 123 | if( rcode ) return; 124 | 125 | ps3_status |= statusPS3Connected; 126 | return; 127 | } 128 | else if((device_descriptor->idVendor == PS3MOVE_VID) && (device_descriptor->idProduct == PS3MOVE_PID)) 129 | { 130 | /* Configure device */ 131 | rcode = UsbPS3.setConf( PS3_ADDR, ep_recordPS3USB[ CONTROL_PIPE ].epAddr, PS3_CONFIGURATION ); 132 | if( rcode ) return; 133 | ps3_status |= statusUSBConfigured; 134 | 135 | MoveController = true; 136 | ps3_status |= statusPS3Connected; 137 | return; 138 | } 139 | } 140 | 141 | 142 | 143 | /* Poll PS3 interrupt pipe and process result if any */ 144 | 145 | void PS3_USB::PS3_poll( void ) 146 | { 147 | 148 | byte rcode = 0; //return code 149 | /* poll PS3 */ 150 | rcode = UsbPS3.inTransfer(PS3_ADDR, ep_recordPS3USB[ INPUT_PIPE ].epAddr, PS3_01_REPORT_LEN, (char *) &report ); 151 | if( rcode ) return; 152 | ps3_status |= statusReportReceived; 153 | return; 154 | } 155 | 156 | unsigned char PS3_USB::getStatus( void ){ 157 | return( ps3_status); 158 | } 159 | 160 | 161 | bool PS3_USB::statConnected( void){ 162 | return(ps3_status & statusPS3Connected); 163 | } 164 | bool PS3_USB::MoveConnected(void) 165 | { 166 | return MoveController; 167 | } 168 | 169 | bool PS3_USB::statReportReceived( void){ 170 | bool rvalue = ps3_status & statusReportReceived; 171 | ps3_status &= ~statusReportReceived; // clear the report received flag 172 | return(rvalue); 173 | } 174 | 175 | unsigned char PS3_USB::getJoystick(unsigned char joy){ 176 | if (joy > 3) return(128); // not valid joystick 177 | return( *(&report.LeftStickX + joy)); 178 | } 179 | 180 | unsigned int PS3_USB::getMotion(unsigned char accel ){ 181 | if(accel > 3) return(512); 182 | return( byteswap(*(&report.AccelX + accel))); 183 | } 184 | 185 | unsigned char PS3_USB::getPressure(unsigned char button ){ 186 | if ((button < 4) || (button > 15)) return(0); 187 | return(*(&report.PressureUp + button - 4)); 188 | } 189 | 190 | bool PS3_USB::buttonChanged(void){ 191 | if ((report.ButtonState != oldbuttonstate) || (report.PSButtonState != oldpsbuttonstate)){ 192 | oldbuttonstate = report.ButtonState; 193 | oldpsbuttonstate = report.PSButtonState; 194 | return(true); 195 | } 196 | return(false); 197 | } 198 | 199 | bool PS3_USB::buttonPressed(unsigned char button){ 200 | if(button == 16) return( report.PSButtonState & 0x01); 201 | return(report.ButtonState & (1 << button)); 202 | 203 | } 204 | 205 | void PS3_USB::LEDRumble(unsigned char ledrum){ 206 | unsigned char i; 207 | char buf[ 64 ] = { 0 }; //General purpose buffer for usb data 208 | /* default buffer values */ 209 | for (i=0; i < PS3_01_REPORT_LEN; i++) buf[i] = pgm_read_byte_near( output_01_report + i); 210 | /* LED setings */ 211 | buf[9] = (ledrum & 0x0f) << 1; 212 | /* rumble settings */ 213 | if (ledrum & 0x30){ 214 | buf[1] = buf[3] = 0xfe; 215 | if (ledrum & 0x10) buf[4] = 0xff; 216 | else buf[2] = 0xff; 217 | } 218 | 219 | UsbPS3.setReport( PS3_ADDR, ep_recordPS3USB[ CONTROL_PIPE ].epAddr, PS3_01_REPORT_LEN, PS3_IF, HID_REPORT_OUTPUT, PS3_01_REPORT_ID , buf ); 220 | 221 | return; 222 | } 223 | 224 | void PS3_USB::setBDADDR(unsigned char * bdaddr) 225 | { 226 | char buf[ PS3_F5_REPORT_LEN ]; 227 | buf[0] = 0x01; 228 | buf[1] = 0x00; 229 | for (int i=0; i < 6; i++){ 230 | buf[i+2] = bdaddr[i]; 231 | } 232 | UsbPS3.setReport( PS3_ADDR, ep_recordPS3USB[ CONTROL_PIPE ].epAddr, PS3_F5_REPORT_LEN, PS3_IF, HID_REPORT_FEATURE, PS3_F5_REPORT_ID , buf ); 233 | return; 234 | } 235 | void PS3_USB::setMoveBDADDR(unsigned char * bdaddr) 236 | { 237 | char buf[11]; 238 | buf[0] = 0x05; 239 | buf[7] = 0x10; 240 | buf[8] = 0x01; 241 | buf[9] = 0x02; 242 | buf[10] = 0x12; 243 | 244 | for (int i = 0; i < 6; i++) 245 | buf[i + 1] = bdaddr[5 - i];//Copy into buffer, has to be written reversed 246 | 247 | //UsbPS3.setReport( PS3_ADDR, 0, 11, 0, HID_REPORT_FEATURE, PS3_F5_REPORT_ID , buf ); 248 | UsbPS3.ctrlReq(PS3_ADDR,0,0x21,0x09,0x05,0x03,0x00,11,buf); 249 | //ctrlReq( byte addr, byte ep, byte bmReqType, byte bRequest, byte wValLo, byte wValHi, unsigned int wInd, unsigned int nbytes, char* dataptr, unsigned int nak_limit ) 250 | return; 251 | } 252 | 253 | void PS3_USB::getBDADDR(unsigned char * bdaddr){ 254 | char buf[ PS3_F5_REPORT_LEN ]; 255 | UsbPS3.getReport( PS3_ADDR, ep_recordPS3USB[ CONTROL_PIPE ].epAddr, PS3_F5_REPORT_LEN, PS3_IF, HID_REPORT_FEATURE, PS3_F5_REPORT_ID , buf ); 256 | for( int i=0; i < 6; i++){ 257 | bdaddr[i] = buf[i + 2]; 258 | } 259 | return; 260 | } -------------------------------------------------------------------------------- /ps3_usb.h: -------------------------------------------------------------------------------- 1 | /* ps3_usb.h - PS3 Game Controller on Arduino USB Host Library 2 | 3 | Copyright (c) 2009 Richard Ibbotson richard.ibbotson@btinternet.com 4 | 5 | All right reserved. This library is free software; you can redistribute it 6 | and/or modify it under the terms of the GNU Lesser General Public License 7 | as published by the Free Software Foundation; either version 2.1 of the License, 8 | or (at your option) any later version. 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | You should have received a copy of the GNU Lesser General Public License along 14 | with this library; if not, write to the Free Software Foundation, Inc., 15 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 16 | 17 | #ifndef _ps3_usb_h_ 18 | #define _ps3_usb_h_ 19 | #include "Usb.h" 20 | #include 21 | 22 | #define byteswap(x) ((x >> 8) | (x << 8)) 23 | 24 | 25 | /* PS3 data taken from descriptors */ 26 | #define PS3_ADDR 1 27 | #define PS3_VID 0x054c //Sony Corporation 28 | #define PS3_PID 0x0268 //PS3 Controller DualShock 3 29 | #define PS3_CONFIGURATION 1 30 | #define PS3_IF 0 31 | #define PS3_NUM_EP 3 32 | #define EP_MAXPKTSIZE 64 33 | #define EP_INTERRUPT 0x03 34 | #define EP_POLL 0x01 35 | #define CONTROL_PIPE 0 36 | #define OUTPUT_PIPE 1 37 | #define INPUT_PIPE 2 38 | 39 | #define PS3NAVIGATION_VID 0x054C//Sony Corporation 40 | #define PS3NAVIGATION_PID 0x042F//Navigation controller 41 | 42 | #define PS3MOVE_VID 0x054C//Sony Corporation 43 | #define PS3MOVE_PID 0x03D5//Motion controller 44 | 45 | /* Defines for bits in ps3_status */ 46 | #define statusDeviceConnected 0x01 47 | #define statusUSBConfigured 0x02 48 | #define statusPS3Connected 0x04 49 | #define statusReportReceived 0x08 50 | 51 | 52 | /* Defines of various parameters for PS3 Game controller reports */ 53 | #define PS3_F4_REPORT_LEN 4 54 | #define PS3_F5_REPORT_LEN 8 55 | #define PS3_01_REPORT_LEN 48 56 | #define HID_REPORT_FEATURE 3 57 | #define HID_REPORT_OUTPUT 2 58 | #define PS3_F4_REPORT_ID 0xF4 59 | #define PS3_01_REPORT_ID 0x01 60 | #define PS3_F5_REPORT_ID 0xF5 61 | 62 | 63 | /* Defines for the PS3 Buttons 64 | */ 65 | 66 | 67 | #define buSelect 0 68 | #define buLAnalog 1 69 | #define buRAnalog 2 70 | #define buStart 3 71 | #define buUp 4 72 | #define buRight 5 73 | #define buDown 6 74 | #define buLeft 7 75 | #define buL2 8 76 | #define buR2 9 77 | #define buL1 10 78 | #define buR1 11 79 | #define buTriangle 12 80 | #define buCircle 13 81 | #define buCross 14 82 | #define buSquare 15 83 | #define buPS 16 84 | 85 | 86 | /* Defines for the PS3 Joysticks 87 | */ 88 | 89 | #define leftJoystickX 0 90 | #define leftJoystickY 1 91 | #define rightJoystickX 2 92 | #define rightJoystickY 3 93 | 94 | 95 | /* Defines for the PS3 Accelerometers and Gyro 96 | */ 97 | 98 | #define AccelerometerX 0 99 | #define AccelerometerY 1 100 | #define AccelerometerZ 2 101 | #define GyrometerZ 3 102 | 103 | /* Defines for the PS3 LED and Rumble 104 | */ 105 | #define psLED1 0x01 106 | #define psLED2 0x02 107 | #define psLED3 0x04 108 | #define psLED4 0x08 109 | #define psRumbleHigh 0x10 110 | #define psRumbleLow 0x20 111 | 112 | //Structure which describes the type 01 input report 113 | typedef struct { 114 | unsigned char ReportType; //Report Type 01 115 | unsigned char Reserved1; // Unknown 116 | unsigned int ButtonState; // Main buttons 117 | unsigned char PSButtonState; // PS button 118 | unsigned char Reserved2; // Unknown 119 | unsigned char LeftStickX; // left Joystick X axis 0 - 255, 128 is mid 120 | unsigned char LeftStickY; // left Joystick Y axis 0 - 255, 128 is mid 121 | unsigned char RightStickX; // right Joystick X axis 0 - 255, 128 is mid 122 | unsigned char RightStickY; // right Joystick Y axis 0 - 255, 128 is mid 123 | unsigned char Reserved3[4]; // Unknown 124 | unsigned char PressureUp; // digital Pad Up button Pressure 0 - 255 125 | unsigned char PressureRight; // digital Pad Right button Pressure 0 - 255 126 | unsigned char PressureDown; // digital Pad Down button Pressure 0 - 255 127 | unsigned char PressureLeft; // digital Pad Left button Pressure 0 - 255 128 | unsigned char PressureL2; // digital Pad L2 button Pressure 0 - 255 129 | unsigned char PressureR2; // digital Pad R2 button Pressure 0 - 255 130 | unsigned char PressureL1; // digital Pad L1 button Pressure 0 - 255 131 | unsigned char PressureR1; // digital Pad R1 button Pressure 0 - 255 132 | unsigned char PressureTriangle; // digital Pad Triangle button Pressure 0 - 255 133 | unsigned char PressureCircle; // digital Pad Circle button Pressure 0 - 255 134 | unsigned char PressureCross; // digital Pad Cross button Pressure 0 - 255 135 | unsigned char PressureSquare; // digital Pad Square button Pressure 0 - 255 136 | unsigned char Reserved4[3]; // Unknown 137 | unsigned char Charge; // charging status ? 02 = charge, 03 = normal 138 | unsigned char Power; // Battery status ? 139 | unsigned char Connection; // Connection Type ? 140 | unsigned char Reserved5[9]; // Unknown 141 | unsigned int AccelX; // X axis accelerometer Big Endian 0 - 1023 142 | unsigned int AccelY; // Y axis accelerometer Big Endian 0 - 1023 143 | unsigned int AccelZ; // Z axis accelerometer Big Endian 0 - 1023 144 | unsigned int GyroZ; // Z axis Gyro Big Endian 0 - 1023 145 | 146 | } TYPE_01_REPORT; 147 | 148 | 149 | class PS3_USB { 150 | 151 | 152 | public: 153 | PS3_USB( void ); 154 | void init(void); 155 | void task( void ); 156 | unsigned char getStatus(void); 157 | bool statConnected(void); 158 | bool statReportReceived(void); 159 | bool MoveConnected(void); 160 | bool buttonChanged(void); 161 | bool buttonPressed(unsigned char); 162 | void LEDRumble(unsigned char); 163 | unsigned int getMotion(unsigned char); 164 | unsigned char getJoystick(unsigned char); 165 | unsigned char getPressure(unsigned char); 166 | void setBDADDR(unsigned char *); 167 | void setMoveBDADDR(unsigned char *); 168 | void getBDADDR(unsigned char *); 169 | TYPE_01_REPORT report; 170 | 171 | private: 172 | void PS3_init(void); 173 | void PS3_poll(void); 174 | }; 175 | 176 | #endif //_ps3_usb_h_ --------------------------------------------------------------------------------