Library to use Arduino USB host shield on mbed

Dependents:   USBHOST_PS5

ArduinoのUSB Host Shield 2.0をmbedで使えるようにしたライブラリです。
大体のコードがArduinoからそのまま移植可能です。

Arduino UNOやMega用のホストシールド以外にもミニサイズのホストシールドでも使用可能です https://os.mbed.com/media/uploads/kotakku/dffgfddswa.png

シールドについて

3.3VのI/O用にシールドの改造が必要になりますがネット上に記事がたくさんあるのでそちらを参考にしてください

接続例

https://os.mbed.com/media/uploads/kotakku/esgsvfvhjrekldkcjxvb.png

使い方

Arduinoのコードと違うのはUSBのインスタンスの宣言部分のみです。
ピンを自分で指定できるようにしたので使いやすくなりました。

仕様

  • Arduinoのmillis関数、micros関数の移植のために内部でTimerクラスを使用しています。

main.cpp

#include "mbed.h"
#include <PS3BT.h>
#include <usbhub.h>

Serial pc(USBTX, USBRX, 115200);

//Nucleo f303k8用
USB Usb(A6, A5, A4, A3, A2); // mosi, miso, sclk, ssel, intr
BTD Btd(&Usb);
PS3BT PS3(&Btd);

int main()
{
    bool printAngle = false;

    if (Usb.Init() == -1)
    {
        pc.printf("\r\nOSC did not start");
        while (1); // Halt
    }
    pc.printf("\r\nPS3 USB Library Started");

    while (1)
    {
        Usb.Task();
        
        if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
            if (PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117)
            {
                pc.printf("\r\nLeftHatX: %d", PS3.getAnalogHat(LeftHatX));
                pc.printf("\tLeftHatY: %d", PS3.getAnalogHat(LeftHatY));
                if (PS3.PS3Connected)
                { // The Navigation controller only have one joystick
                    pc.printf("\tRightHatX: %d", PS3.getAnalogHat(RightHatX));
                    pc.printf("\tRightHatY: %d", PS3.getAnalogHat(RightHatY));
                }
            }
            // Analog button values can be read from almost all buttons
            if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2))
            {
                pc.printf("\r\nL2: %d", PS3.getAnalogButton(L2));
                if (!PS3.PS3NavigationConnected)
                {
                    pc.printf("\tR2: %d", PS3.getAnalogButton(R2));
                }
            }
            if (PS3.getButtonClick(PS))
            {
                PS3.disconnect();
                pc.printf("\r\nPS");
            }
    
            if (PS3.getButtonClick(TRIANGLE))
                pc.printf("\r\nTriangle");
            if (PS3.getButtonClick(CIRCLE))
                pc.printf("\r\nCircle");
            if (PS3.getButtonClick(CROSS))
                pc.printf("\r\nCross");
            if (PS3.getButtonClick(SQUARE))
                pc.printf("\r\nSquare");
    
            if (PS3.getButtonClick(UP))
            {
                pc.printf("\r\nUp");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED4);
            }
            if (PS3.getButtonClick(RIGHT))
            {
                pc.printf("\r\nRight");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED1);
            }
            if (PS3.getButtonClick(DOWN))
            {
                pc.printf("\r\nDown");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED2);
            }
            if (PS3.getButtonClick(LEFT))
            {
                pc.printf("\r\nLeft");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED3);
            }
    
            if (PS3.getButtonClick(L1))
                pc.printf("\r\nL1");
            if (PS3.getButtonClick(L3))
                pc.printf("\r\nL3");
            if (PS3.getButtonClick(R1))
                pc.printf("\r\nR1");
            if (PS3.getButtonClick(R3))
                pc.printf("\r\nR3");
    
            if (PS3.getButtonClick(SELECT))
            {
                pc.printf("\r\nSelect - ");
                PS3.printStatusString();
            }
            if (PS3.getButtonClick(START))
            {
                pc.printf("\r\nStart");
                printAngle = !printAngle;
            }
            if (printAngle)
            {
                pc.printf("\r\nPitch: %.3lf", PS3.getAngle(Pitch));
                pc.printf("\tRoll: %.3lf", PS3.getAngle(Roll));
            }
        }
        else
        {
            pc.printf("not connect\n");
        }
    }
}
Committer:
robo_ichinoseki_a
Date:
Sat May 02 05:56:48 2020 +0000
Revision:
1:da31140f2a1c
Parent:
0:b1ce54272580
update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kotakku 0:b1ce54272580 1 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
kotakku 0:b1ce54272580 2
kotakku 0:b1ce54272580 3 This software may be distributed and modified under the terms of the GNU
kotakku 0:b1ce54272580 4 General Public License version 2 (GPL2) as published by the Free Software
kotakku 0:b1ce54272580 5 Foundation and appearing in the file GPL2.TXT included in the packaging of
kotakku 0:b1ce54272580 6 this file. Please note that GPL2 Section 2[b] requires that all works based
kotakku 0:b1ce54272580 7 on this software must also be made publicly available under the terms of
kotakku 0:b1ce54272580 8 the GPL2 ("Copyleft").
kotakku 0:b1ce54272580 9
kotakku 0:b1ce54272580 10 Contact information
kotakku 0:b1ce54272580 11 -------------------
kotakku 0:b1ce54272580 12
kotakku 0:b1ce54272580 13 Kristian Lauszus, TKJ Electronics
kotakku 0:b1ce54272580 14 Web : http://www.tkjelectronics.com
kotakku 0:b1ce54272580 15 e-mail : kristianl@tkjelectronics.com
kotakku 0:b1ce54272580 16
kotakku 0:b1ce54272580 17 getBatteryLevel and checkStatus functions made by timstamp.co.uk found using BusHound from Perisoft.net
kotakku 0:b1ce54272580 18 */
kotakku 0:b1ce54272580 19
kotakku 0:b1ce54272580 20 #include "XBOXRECV.h"
kotakku 0:b1ce54272580 21 // To enable serial debugging see "settings.h"
kotakku 0:b1ce54272580 22 //#define EXTRADEBUG // Uncomment to get even more debugging data
kotakku 0:b1ce54272580 23 //#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
kotakku 0:b1ce54272580 24
kotakku 0:b1ce54272580 25 XBOXRECV::XBOXRECV(USB *p) :
kotakku 0:b1ce54272580 26 pUsb(p), // pointer to USB class instance - mandatory
kotakku 0:b1ce54272580 27 bAddress(0), // device address - mandatory
kotakku 0:b1ce54272580 28 bPollEnable(false) { // don't start polling before dongle is connected
kotakku 0:b1ce54272580 29 for(uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
kotakku 0:b1ce54272580 30 epInfo[i].epAddr = 0;
kotakku 0:b1ce54272580 31 epInfo[i].maxPktSize = (i) ? 0 : 8;
kotakku 0:b1ce54272580 32 epInfo[i].bmSndToggle = 0;
kotakku 0:b1ce54272580 33 epInfo[i].bmRcvToggle = 0;
kotakku 0:b1ce54272580 34 epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
kotakku 0:b1ce54272580 35 }
kotakku 0:b1ce54272580 36
kotakku 0:b1ce54272580 37 if(pUsb) // register in USB subsystem
kotakku 0:b1ce54272580 38 pUsb->RegisterDeviceClass(this); //set devConfig[] entry
kotakku 0:b1ce54272580 39 }
kotakku 0:b1ce54272580 40
kotakku 0:b1ce54272580 41 uint8_t XBOXRECV::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
kotakku 0:b1ce54272580 42 const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
kotakku 0:b1ce54272580 43 uint8_t buf[constBufSize];
kotakku 0:b1ce54272580 44 USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
kotakku 0:b1ce54272580 45 uint8_t rcode;
kotakku 0:b1ce54272580 46 UsbDevice *p = NULL;
kotakku 0:b1ce54272580 47 EpInfo *oldep_ptr = NULL;
kotakku 0:b1ce54272580 48 uint16_t PID, VID;
kotakku 0:b1ce54272580 49
kotakku 0:b1ce54272580 50 AddressPool &addrPool = pUsb->GetAddressPool(); // Get memory address of USB device address pool
kotakku 0:b1ce54272580 51 #ifdef EXTRADEBUG
kotakku 0:b1ce54272580 52 Notify(PSTR("\r\nXBOXRECV Init"), 0x80);
kotakku 0:b1ce54272580 53 #endif
kotakku 0:b1ce54272580 54
kotakku 0:b1ce54272580 55 if(bAddress) { // Check if address has already been assigned to an instance
kotakku 0:b1ce54272580 56 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 57 Notify(PSTR("\r\nAddress in use"), 0x80);
kotakku 0:b1ce54272580 58 #endif
kotakku 0:b1ce54272580 59 return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
kotakku 0:b1ce54272580 60 }
kotakku 0:b1ce54272580 61
kotakku 0:b1ce54272580 62 p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned
kotakku 0:b1ce54272580 63
kotakku 0:b1ce54272580 64 if(!p) {
kotakku 0:b1ce54272580 65 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 66 Notify(PSTR("\r\nAddress not found"), 0x80);
kotakku 0:b1ce54272580 67 #endif
kotakku 0:b1ce54272580 68 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
kotakku 0:b1ce54272580 69 }
kotakku 0:b1ce54272580 70
kotakku 0:b1ce54272580 71 if(!p->epinfo) {
kotakku 0:b1ce54272580 72 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 73 Notify(PSTR("\r\nepinfo is null"), 0x80);
kotakku 0:b1ce54272580 74 #endif
kotakku 0:b1ce54272580 75 return USB_ERROR_EPINFO_IS_NULL;
kotakku 0:b1ce54272580 76 }
kotakku 0:b1ce54272580 77
kotakku 0:b1ce54272580 78 oldep_ptr = p->epinfo; // Save old pointer to EP_RECORD of address 0
kotakku 0:b1ce54272580 79 p->epinfo = epInfo; // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
kotakku 0:b1ce54272580 80 p->lowspeed = lowspeed;
kotakku 0:b1ce54272580 81
kotakku 0:b1ce54272580 82 rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
kotakku 0:b1ce54272580 83
kotakku 0:b1ce54272580 84 p->epinfo = oldep_ptr; // Restore p->epinfo
kotakku 0:b1ce54272580 85
kotakku 0:b1ce54272580 86 if(rcode)
kotakku 0:b1ce54272580 87 goto FailGetDevDescr;
kotakku 0:b1ce54272580 88
kotakku 0:b1ce54272580 89 VID = udd->idVendor;
kotakku 0:b1ce54272580 90 PID = udd->idProduct;
kotakku 0:b1ce54272580 91
kotakku 0:b1ce54272580 92 if((VID != XBOX_VID && VID != MADCATZ_VID && VID != JOYTECH_VID) || (PID != XBOX_WIRELESS_RECEIVER_PID && PID != XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID)) { // Check if it's a Xbox receiver using the Vendor ID and Product ID
kotakku 0:b1ce54272580 93 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 94 Notify(PSTR("\r\nYou'll need a wireless receiver for this libary to work"), 0x80);
kotakku 0:b1ce54272580 95 #endif
kotakku 0:b1ce54272580 96 goto FailUnknownDevice;
kotakku 0:b1ce54272580 97 }
kotakku 0:b1ce54272580 98
kotakku 0:b1ce54272580 99 bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class
kotakku 0:b1ce54272580 100
kotakku 0:b1ce54272580 101 if(!bAddress) {
kotakku 0:b1ce54272580 102 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 103 Notify(PSTR("\r\nOut of address space"), 0x80);
kotakku 0:b1ce54272580 104 #endif
kotakku 0:b1ce54272580 105 return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
kotakku 0:b1ce54272580 106 }
kotakku 0:b1ce54272580 107
kotakku 0:b1ce54272580 108 epInfo[0].maxPktSize = udd->bMaxPacketSize0; // Extract Max Packet Size from device descriptor
kotakku 0:b1ce54272580 109
kotakku 0:b1ce54272580 110 delay(20); // Wait a little before resetting device
kotakku 0:b1ce54272580 111
kotakku 0:b1ce54272580 112 return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET;
kotakku 0:b1ce54272580 113
kotakku 0:b1ce54272580 114 /* Diagnostic messages */
kotakku 0:b1ce54272580 115 FailGetDevDescr:
kotakku 0:b1ce54272580 116 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 117 NotifyFailGetDevDescr(rcode);
kotakku 0:b1ce54272580 118 #endif
kotakku 0:b1ce54272580 119 if(rcode != hrJERR)
kotakku 0:b1ce54272580 120 rcode = USB_ERROR_FailGetDevDescr;
kotakku 0:b1ce54272580 121 goto Fail;
kotakku 0:b1ce54272580 122
kotakku 0:b1ce54272580 123 FailUnknownDevice:
kotakku 0:b1ce54272580 124 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 125 NotifyFailUnknownDevice(VID, PID);
kotakku 0:b1ce54272580 126 #endif
kotakku 0:b1ce54272580 127 rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
kotakku 0:b1ce54272580 128
kotakku 0:b1ce54272580 129 Fail:
kotakku 0:b1ce54272580 130 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 131 Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
kotakku 0:b1ce54272580 132 NotifyFail(rcode);
kotakku 0:b1ce54272580 133 #endif
kotakku 0:b1ce54272580 134 Release();
kotakku 0:b1ce54272580 135 return rcode;
kotakku 0:b1ce54272580 136 };
kotakku 0:b1ce54272580 137
kotakku 0:b1ce54272580 138 uint8_t XBOXRECV::Init(uint8_t parent __attribute__((unused)), uint8_t port __attribute__((unused)), bool lowspeed) {
kotakku 0:b1ce54272580 139 uint8_t rcode;
kotakku 0:b1ce54272580 140
kotakku 0:b1ce54272580 141 AddressPool &addrPool = pUsb->GetAddressPool();
kotakku 0:b1ce54272580 142 #ifdef EXTRADEBUG
kotakku 0:b1ce54272580 143 Notify(PSTR("\r\nBTD Init"), 0x80);
kotakku 0:b1ce54272580 144 #endif
kotakku 0:b1ce54272580 145 UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
kotakku 0:b1ce54272580 146
kotakku 0:b1ce54272580 147 if(!p) {
kotakku 0:b1ce54272580 148 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 149 Notify(PSTR("\r\nAddress not found"), 0x80);
kotakku 0:b1ce54272580 150 #endif
kotakku 0:b1ce54272580 151 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
kotakku 0:b1ce54272580 152 }
kotakku 0:b1ce54272580 153
kotakku 0:b1ce54272580 154 delay(300); // Assign new address to the device
kotakku 0:b1ce54272580 155
kotakku 0:b1ce54272580 156 rcode = pUsb->setAddr(0, 0, bAddress); // Assign new address to the device
kotakku 0:b1ce54272580 157 if(rcode) {
kotakku 0:b1ce54272580 158 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 159 Notify(PSTR("\r\nsetAddr: "), 0x80);
kotakku 0:b1ce54272580 160 D_PrintHex<uint8_t > (rcode, 0x80);
kotakku 0:b1ce54272580 161 #endif
kotakku 0:b1ce54272580 162 p->lowspeed = false;
kotakku 0:b1ce54272580 163 goto Fail;
kotakku 0:b1ce54272580 164 }
kotakku 0:b1ce54272580 165 #ifdef EXTRADEBUG
kotakku 0:b1ce54272580 166 Notify(PSTR("\r\nAddr: "), 0x80);
kotakku 0:b1ce54272580 167 D_PrintHex<uint8_t > (bAddress, 0x80);
kotakku 0:b1ce54272580 168 #endif
kotakku 0:b1ce54272580 169
kotakku 0:b1ce54272580 170 p->lowspeed = false;
kotakku 0:b1ce54272580 171
kotakku 0:b1ce54272580 172 p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
kotakku 0:b1ce54272580 173 if(!p) {
kotakku 0:b1ce54272580 174 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 175 Notify(PSTR("\r\nAddress not found"), 0x80);
kotakku 0:b1ce54272580 176 #endif
kotakku 0:b1ce54272580 177 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
kotakku 0:b1ce54272580 178 }
kotakku 0:b1ce54272580 179
kotakku 0:b1ce54272580 180 p->lowspeed = lowspeed;
kotakku 0:b1ce54272580 181
kotakku 0:b1ce54272580 182 rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known
kotakku 0:b1ce54272580 183 if(rcode)
kotakku 0:b1ce54272580 184 goto FailSetDevTblEntry;
kotakku 0:b1ce54272580 185
kotakku 0:b1ce54272580 186 /* The application will work in reduced host mode, so we can save program and data
kotakku 0:b1ce54272580 187 memory space. After verifying the VID we will use known values for the
kotakku 0:b1ce54272580 188 configuration values for device, interface, endpoints and HID for the XBOX360 Wireless receiver */
kotakku 0:b1ce54272580 189
kotakku 0:b1ce54272580 190 /* Initialize data structures for endpoints of device */
kotakku 0:b1ce54272580 191 epInfo[ XBOX_INPUT_PIPE_1 ].epAddr = 0x01; // XBOX 360 report endpoint - poll interval 1ms
kotakku 0:b1ce54272580 192 epInfo[ XBOX_INPUT_PIPE_1 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
kotakku 0:b1ce54272580 193 epInfo[ XBOX_INPUT_PIPE_1 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
kotakku 0:b1ce54272580 194 epInfo[ XBOX_INPUT_PIPE_1 ].maxPktSize = EP_MAXPKTSIZE;
kotakku 0:b1ce54272580 195 epInfo[ XBOX_INPUT_PIPE_1 ].bmSndToggle = 0;
kotakku 0:b1ce54272580 196 epInfo[ XBOX_INPUT_PIPE_1 ].bmRcvToggle = 0;
kotakku 0:b1ce54272580 197 epInfo[ XBOX_OUTPUT_PIPE_1 ].epAddr = 0x01; // XBOX 360 output endpoint - poll interval 8ms
kotakku 0:b1ce54272580 198 epInfo[ XBOX_OUTPUT_PIPE_1 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
kotakku 0:b1ce54272580 199 epInfo[ XBOX_OUTPUT_PIPE_1 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
kotakku 0:b1ce54272580 200 epInfo[ XBOX_OUTPUT_PIPE_1 ].maxPktSize = EP_MAXPKTSIZE;
kotakku 0:b1ce54272580 201 epInfo[ XBOX_OUTPUT_PIPE_1 ].bmSndToggle = 0;
kotakku 0:b1ce54272580 202 epInfo[ XBOX_OUTPUT_PIPE_1 ].bmRcvToggle = 0;
kotakku 0:b1ce54272580 203
kotakku 0:b1ce54272580 204 epInfo[ XBOX_INPUT_PIPE_2 ].epAddr = 0x03; // XBOX 360 report endpoint - poll interval 1ms
kotakku 0:b1ce54272580 205 epInfo[ XBOX_INPUT_PIPE_2 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
kotakku 0:b1ce54272580 206 epInfo[ XBOX_INPUT_PIPE_2 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
kotakku 0:b1ce54272580 207 epInfo[ XBOX_INPUT_PIPE_2 ].maxPktSize = EP_MAXPKTSIZE;
kotakku 0:b1ce54272580 208 epInfo[ XBOX_INPUT_PIPE_2 ].bmSndToggle = 0;
kotakku 0:b1ce54272580 209 epInfo[ XBOX_INPUT_PIPE_2 ].bmRcvToggle = 0;
kotakku 0:b1ce54272580 210 epInfo[ XBOX_OUTPUT_PIPE_2 ].epAddr = 0x03; // XBOX 360 output endpoint - poll interval 8ms
kotakku 0:b1ce54272580 211 epInfo[ XBOX_OUTPUT_PIPE_2 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
kotakku 0:b1ce54272580 212 epInfo[ XBOX_OUTPUT_PIPE_2 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
kotakku 0:b1ce54272580 213 epInfo[ XBOX_OUTPUT_PIPE_2 ].maxPktSize = EP_MAXPKTSIZE;
kotakku 0:b1ce54272580 214 epInfo[ XBOX_OUTPUT_PIPE_2 ].bmSndToggle = 0;
kotakku 0:b1ce54272580 215 epInfo[ XBOX_OUTPUT_PIPE_2 ].bmRcvToggle = 0;
kotakku 0:b1ce54272580 216
kotakku 0:b1ce54272580 217 epInfo[ XBOX_INPUT_PIPE_3 ].epAddr = 0x05; // XBOX 360 report endpoint - poll interval 1ms
kotakku 0:b1ce54272580 218 epInfo[ XBOX_INPUT_PIPE_3 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
kotakku 0:b1ce54272580 219 epInfo[ XBOX_INPUT_PIPE_3 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
kotakku 0:b1ce54272580 220 epInfo[ XBOX_INPUT_PIPE_3 ].maxPktSize = EP_MAXPKTSIZE;
kotakku 0:b1ce54272580 221 epInfo[ XBOX_INPUT_PIPE_3 ].bmSndToggle = 0;
kotakku 0:b1ce54272580 222 epInfo[ XBOX_INPUT_PIPE_3 ].bmRcvToggle = 0;
kotakku 0:b1ce54272580 223 epInfo[ XBOX_OUTPUT_PIPE_3 ].epAddr = 0x05; // XBOX 360 output endpoint - poll interval 8ms
kotakku 0:b1ce54272580 224 epInfo[ XBOX_OUTPUT_PIPE_3 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
kotakku 0:b1ce54272580 225 epInfo[ XBOX_OUTPUT_PIPE_3 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
kotakku 0:b1ce54272580 226 epInfo[ XBOX_OUTPUT_PIPE_3 ].maxPktSize = EP_MAXPKTSIZE;
kotakku 0:b1ce54272580 227 epInfo[ XBOX_OUTPUT_PIPE_3 ].bmSndToggle = 0;
kotakku 0:b1ce54272580 228 epInfo[ XBOX_OUTPUT_PIPE_3 ].bmRcvToggle = 0;
kotakku 0:b1ce54272580 229
kotakku 0:b1ce54272580 230 epInfo[ XBOX_INPUT_PIPE_4 ].epAddr = 0x07; // XBOX 360 report endpoint - poll interval 1ms
kotakku 0:b1ce54272580 231 epInfo[ XBOX_INPUT_PIPE_4 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
kotakku 0:b1ce54272580 232 epInfo[ XBOX_INPUT_PIPE_4 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
kotakku 0:b1ce54272580 233 epInfo[ XBOX_INPUT_PIPE_4 ].maxPktSize = EP_MAXPKTSIZE;
kotakku 0:b1ce54272580 234 epInfo[ XBOX_INPUT_PIPE_4 ].bmSndToggle = 0;
kotakku 0:b1ce54272580 235 epInfo[ XBOX_INPUT_PIPE_4 ].bmRcvToggle = 0;
kotakku 0:b1ce54272580 236 epInfo[ XBOX_OUTPUT_PIPE_4 ].epAddr = 0x07; // XBOX 360 output endpoint - poll interval 8ms
kotakku 0:b1ce54272580 237 epInfo[ XBOX_OUTPUT_PIPE_4 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
kotakku 0:b1ce54272580 238 epInfo[ XBOX_OUTPUT_PIPE_4 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
kotakku 0:b1ce54272580 239 epInfo[ XBOX_OUTPUT_PIPE_4 ].maxPktSize = EP_MAXPKTSIZE;
kotakku 0:b1ce54272580 240 epInfo[ XBOX_OUTPUT_PIPE_4 ].bmSndToggle = 0;
kotakku 0:b1ce54272580 241 epInfo[ XBOX_OUTPUT_PIPE_4 ].bmRcvToggle = 0;
kotakku 0:b1ce54272580 242
kotakku 0:b1ce54272580 243 rcode = pUsb->setEpInfoEntry(bAddress, 9, epInfo);
kotakku 0:b1ce54272580 244 if(rcode)
kotakku 0:b1ce54272580 245 goto FailSetDevTblEntry;
kotakku 0:b1ce54272580 246
kotakku 0:b1ce54272580 247 delay(200); //Give time for address change
kotakku 0:b1ce54272580 248
kotakku 0:b1ce54272580 249 rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
kotakku 0:b1ce54272580 250 if(rcode)
kotakku 0:b1ce54272580 251 goto FailSetConfDescr;
kotakku 0:b1ce54272580 252
kotakku 0:b1ce54272580 253 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 254 Notify(PSTR("\r\nXbox Wireless Receiver Connected\r\n"), 0x80);
kotakku 0:b1ce54272580 255 #endif
kotakku 0:b1ce54272580 256 XboxReceiverConnected = true;
kotakku 0:b1ce54272580 257 bPollEnable = true;
kotakku 0:b1ce54272580 258 checkStatusTimer = 0; // Reset timer
kotakku 0:b1ce54272580 259 return 0; // Successful configuration
kotakku 0:b1ce54272580 260
kotakku 0:b1ce54272580 261 /* Diagnostic messages */
kotakku 0:b1ce54272580 262 FailSetDevTblEntry:
kotakku 0:b1ce54272580 263 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 264 NotifyFailSetDevTblEntry();
kotakku 0:b1ce54272580 265 goto Fail;
kotakku 0:b1ce54272580 266 #endif
kotakku 0:b1ce54272580 267
kotakku 0:b1ce54272580 268 FailSetConfDescr:
kotakku 0:b1ce54272580 269 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 270 NotifyFailSetConfDescr();
kotakku 0:b1ce54272580 271 #endif
kotakku 0:b1ce54272580 272
kotakku 0:b1ce54272580 273 Fail:
kotakku 0:b1ce54272580 274 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 275 Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
kotakku 0:b1ce54272580 276 NotifyFail(rcode);
kotakku 0:b1ce54272580 277 #endif
kotakku 0:b1ce54272580 278 Release();
kotakku 0:b1ce54272580 279 return rcode;
kotakku 0:b1ce54272580 280 }
kotakku 0:b1ce54272580 281
kotakku 0:b1ce54272580 282 /* Performs a cleanup after failed Init() attempt */
kotakku 0:b1ce54272580 283 uint8_t XBOXRECV::Release() {
kotakku 0:b1ce54272580 284 XboxReceiverConnected = false;
kotakku 0:b1ce54272580 285 for(uint8_t i = 0; i < 4; i++)
kotakku 0:b1ce54272580 286 Xbox360Connected[i] = 0x00;
kotakku 0:b1ce54272580 287 pUsb->GetAddressPool().FreeAddress(bAddress);
kotakku 0:b1ce54272580 288 bAddress = 0;
kotakku 0:b1ce54272580 289 bPollEnable = false;
kotakku 0:b1ce54272580 290 return 0;
kotakku 0:b1ce54272580 291 }
kotakku 0:b1ce54272580 292
kotakku 0:b1ce54272580 293 uint8_t XBOXRECV::Poll() {
kotakku 0:b1ce54272580 294 if(!bPollEnable)
kotakku 0:b1ce54272580 295 return 0;
kotakku 0:b1ce54272580 296 if(!checkStatusTimer || ((int32_t)((uint32_t)millis() - checkStatusTimer) > 3000)) { // Run checkStatus every 3 seconds
kotakku 0:b1ce54272580 297 checkStatusTimer = (uint32_t)millis();
kotakku 0:b1ce54272580 298 checkStatus();
kotakku 0:b1ce54272580 299 }
kotakku 0:b1ce54272580 300
kotakku 0:b1ce54272580 301 uint8_t inputPipe;
kotakku 0:b1ce54272580 302 uint16_t bufferSize;
kotakku 0:b1ce54272580 303 for(uint8_t i = 0; i < 4; i++) {
kotakku 0:b1ce54272580 304 if(i == 0)
kotakku 0:b1ce54272580 305 inputPipe = XBOX_INPUT_PIPE_1;
kotakku 0:b1ce54272580 306 else if(i == 1)
kotakku 0:b1ce54272580 307 inputPipe = XBOX_INPUT_PIPE_2;
kotakku 0:b1ce54272580 308 else if(i == 2)
kotakku 0:b1ce54272580 309 inputPipe = XBOX_INPUT_PIPE_3;
kotakku 0:b1ce54272580 310 else
kotakku 0:b1ce54272580 311 inputPipe = XBOX_INPUT_PIPE_4;
kotakku 0:b1ce54272580 312
kotakku 0:b1ce54272580 313 bufferSize = EP_MAXPKTSIZE; // This is the maximum number of bytes we want to receive
kotakku 0:b1ce54272580 314 pUsb->inTransfer(bAddress, epInfo[ inputPipe ].epAddr, &bufferSize, readBuf);
kotakku 0:b1ce54272580 315 if(bufferSize > 0) { // The number of received bytes
kotakku 0:b1ce54272580 316 #ifdef EXTRADEBUG
kotakku 0:b1ce54272580 317 Notify(PSTR("Bytes Received: "), 0x80);
kotakku 0:b1ce54272580 318 D_PrintHex<uint16_t > (bufferSize, 0x80);
kotakku 0:b1ce54272580 319 Notify(PSTR("\r\n"), 0x80);
kotakku 0:b1ce54272580 320 #endif
kotakku 0:b1ce54272580 321 readReport(i);
kotakku 0:b1ce54272580 322 #ifdef PRINTREPORT
kotakku 0:b1ce54272580 323 printReport(i, bufferSize); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
kotakku 0:b1ce54272580 324 #endif
kotakku 0:b1ce54272580 325 }
kotakku 0:b1ce54272580 326 }
kotakku 0:b1ce54272580 327 return 0;
kotakku 0:b1ce54272580 328 }
kotakku 0:b1ce54272580 329
kotakku 0:b1ce54272580 330 void XBOXRECV::readReport(uint8_t controller) {
kotakku 0:b1ce54272580 331 if(readBuf == NULL)
kotakku 0:b1ce54272580 332 return;
kotakku 0:b1ce54272580 333 // This report is send when a controller is connected and disconnected
kotakku 0:b1ce54272580 334 if(readBuf[0] == 0x08 && readBuf[1] != Xbox360Connected[controller]) {
kotakku 0:b1ce54272580 335 Xbox360Connected[controller] = readBuf[1];
kotakku 0:b1ce54272580 336 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 337 Notify(PSTR("Controller "), 0x80);
kotakku 0:b1ce54272580 338 Notify(controller, 0x80);
kotakku 0:b1ce54272580 339 #endif
kotakku 0:b1ce54272580 340 if(Xbox360Connected[controller]) {
kotakku 0:b1ce54272580 341 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 342 const char* str = 0;
kotakku 0:b1ce54272580 343 switch(readBuf[1]) {
kotakku 0:b1ce54272580 344 case 0x80: str = PSTR(" as controller\r\n");
kotakku 0:b1ce54272580 345 break;
kotakku 0:b1ce54272580 346 case 0x40: str = PSTR(" as headset\r\n");
kotakku 0:b1ce54272580 347 break;
kotakku 0:b1ce54272580 348 case 0xC0: str = PSTR(" as controller+headset\r\n");
kotakku 0:b1ce54272580 349 break;
kotakku 0:b1ce54272580 350 }
kotakku 0:b1ce54272580 351 Notify(PSTR(": connected"), 0x80);
kotakku 0:b1ce54272580 352 Notify(str, 0x80);
kotakku 0:b1ce54272580 353 #endif
kotakku 0:b1ce54272580 354 onInit(controller);
kotakku 0:b1ce54272580 355 }
kotakku 0:b1ce54272580 356 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 357 else
kotakku 0:b1ce54272580 358 Notify(PSTR(": disconnected\r\n"), 0x80);
kotakku 0:b1ce54272580 359 #endif
kotakku 0:b1ce54272580 360 return;
kotakku 0:b1ce54272580 361 }
kotakku 0:b1ce54272580 362 // Controller status report
kotakku 0:b1ce54272580 363 if(readBuf[1] == 0x00 && readBuf[3] & 0x13 && readBuf[4] >= 0x22) {
kotakku 0:b1ce54272580 364 controllerStatus[controller] = ((uint16_t)readBuf[3] << 8) | readBuf[4];
kotakku 0:b1ce54272580 365 return;
kotakku 0:b1ce54272580 366 }
kotakku 0:b1ce54272580 367 if(readBuf[1] != 0x01) // Check if it's the correct report - the receiver also sends different status reports
kotakku 0:b1ce54272580 368 return;
kotakku 0:b1ce54272580 369
kotakku 0:b1ce54272580 370 // A controller must be connected if it's sending data
kotakku 0:b1ce54272580 371 if(!Xbox360Connected[controller])
kotakku 0:b1ce54272580 372 Xbox360Connected[controller] |= 0x80;
kotakku 0:b1ce54272580 373
kotakku 0:b1ce54272580 374 ButtonState[controller] = (uint32_t)(readBuf[9] | ((uint16_t)readBuf[8] << 8) | ((uint32_t)readBuf[7] << 16) | ((uint32_t)readBuf[6] << 24));
kotakku 0:b1ce54272580 375
kotakku 0:b1ce54272580 376 hatValue[controller][LeftHatX] = (int16_t)(((uint16_t)readBuf[11] << 8) | readBuf[10]);
kotakku 0:b1ce54272580 377 hatValue[controller][LeftHatY] = (int16_t)(((uint16_t)readBuf[13] << 8) | readBuf[12]);
kotakku 0:b1ce54272580 378 hatValue[controller][RightHatX] = (int16_t)(((uint16_t)readBuf[15] << 8) | readBuf[14]);
kotakku 0:b1ce54272580 379 hatValue[controller][RightHatY] = (int16_t)(((uint16_t)readBuf[17] << 8) | readBuf[16]);
kotakku 0:b1ce54272580 380
kotakku 0:b1ce54272580 381 //Notify(PSTR("\r\nButtonState: "), 0x80);
kotakku 0:b1ce54272580 382 //PrintHex<uint32_t>(ButtonState[controller], 0x80);
kotakku 0:b1ce54272580 383
kotakku 0:b1ce54272580 384 if(ButtonState[controller] != OldButtonState[controller]) {
kotakku 0:b1ce54272580 385 buttonStateChanged[controller] = true;
kotakku 0:b1ce54272580 386 ButtonClickState[controller] = (ButtonState[controller] >> 16) & ((~OldButtonState[controller]) >> 16); // Update click state variable, but don't include the two trigger buttons L2 and R2
kotakku 0:b1ce54272580 387 if(((uint8_t)OldButtonState[controller]) == 0 && ((uint8_t)ButtonState[controller]) != 0) // The L2 and R2 buttons are special as they are analog buttons
kotakku 0:b1ce54272580 388 R2Clicked[controller] = true;
kotakku 0:b1ce54272580 389 if((uint8_t)(OldButtonState[controller] >> 8) == 0 && (uint8_t)(ButtonState[controller] >> 8) != 0)
kotakku 0:b1ce54272580 390 L2Clicked[controller] = true;
kotakku 0:b1ce54272580 391 OldButtonState[controller] = ButtonState[controller];
kotakku 0:b1ce54272580 392 }
kotakku 0:b1ce54272580 393 }
kotakku 0:b1ce54272580 394
kotakku 0:b1ce54272580 395 void XBOXRECV::printReport(uint8_t controller __attribute__((unused)), uint8_t nBytes __attribute__((unused))) { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
kotakku 0:b1ce54272580 396 #ifdef PRINTREPORT
kotakku 0:b1ce54272580 397 if(readBuf == NULL)
kotakku 0:b1ce54272580 398 return;
kotakku 0:b1ce54272580 399 Notify(PSTR("Controller "), 0x80);
kotakku 0:b1ce54272580 400 Notify(controller, 0x80);
kotakku 0:b1ce54272580 401 Notify(PSTR(": "), 0x80);
kotakku 0:b1ce54272580 402 for(uint8_t i = 0; i < nBytes; i++) {
kotakku 0:b1ce54272580 403 D_PrintHex<uint8_t > (readBuf[i], 0x80);
kotakku 0:b1ce54272580 404 Notify(PSTR(" "), 0x80);
kotakku 0:b1ce54272580 405 }
kotakku 0:b1ce54272580 406 Notify(PSTR("\r\n"), 0x80);
kotakku 0:b1ce54272580 407 #endif
kotakku 0:b1ce54272580 408 }
kotakku 0:b1ce54272580 409
kotakku 0:b1ce54272580 410 uint8_t XBOXRECV::getButtonPress(ButtonEnum b, uint8_t controller) {
kotakku 0:b1ce54272580 411 if(b == L2) // These are analog buttons
kotakku 0:b1ce54272580 412 return (uint8_t)(ButtonState[controller] >> 8);
kotakku 0:b1ce54272580 413 else if(b == R2)
kotakku 0:b1ce54272580 414 return (uint8_t)ButtonState[controller];
kotakku 0:b1ce54272580 415 return (bool)(ButtonState[controller] & ((uint32_t)pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]) << 16));
kotakku 0:b1ce54272580 416 }
kotakku 0:b1ce54272580 417
kotakku 0:b1ce54272580 418 bool XBOXRECV::getButtonClick(ButtonEnum b, uint8_t controller) {
kotakku 0:b1ce54272580 419 if(b == L2) {
kotakku 0:b1ce54272580 420 if(L2Clicked[controller]) {
kotakku 0:b1ce54272580 421 L2Clicked[controller] = false;
kotakku 0:b1ce54272580 422 return true;
kotakku 0:b1ce54272580 423 }
kotakku 0:b1ce54272580 424 return false;
kotakku 0:b1ce54272580 425 } else if(b == R2) {
kotakku 0:b1ce54272580 426 if(R2Clicked[controller]) {
kotakku 0:b1ce54272580 427 R2Clicked[controller] = false;
kotakku 0:b1ce54272580 428 return true;
kotakku 0:b1ce54272580 429 }
kotakku 0:b1ce54272580 430 return false;
kotakku 0:b1ce54272580 431 }
kotakku 0:b1ce54272580 432 uint16_t button = pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]);
kotakku 0:b1ce54272580 433 bool click = (ButtonClickState[controller] & button);
kotakku 0:b1ce54272580 434 ButtonClickState[controller] &= ~button; // clear "click" event
kotakku 0:b1ce54272580 435 return click;
kotakku 0:b1ce54272580 436 }
kotakku 0:b1ce54272580 437
kotakku 0:b1ce54272580 438 int16_t XBOXRECV::getAnalogHat(AnalogHatEnum a, uint8_t controller) {
kotakku 0:b1ce54272580 439 return hatValue[controller][a];
kotakku 0:b1ce54272580 440 }
kotakku 0:b1ce54272580 441
kotakku 0:b1ce54272580 442 bool XBOXRECV::buttonChanged(uint8_t controller) {
kotakku 0:b1ce54272580 443 bool state = buttonStateChanged[controller];
kotakku 0:b1ce54272580 444 buttonStateChanged[controller] = false;
kotakku 0:b1ce54272580 445 return state;
kotakku 0:b1ce54272580 446 }
kotakku 0:b1ce54272580 447
kotakku 0:b1ce54272580 448 /*
kotakku 0:b1ce54272580 449 ControllerStatus Breakdown
kotakku 0:b1ce54272580 450 ControllerStatus[controller] & 0x0001 // 0
kotakku 0:b1ce54272580 451 ControllerStatus[controller] & 0x0002 // normal batteries, no rechargeable battery pack
kotakku 0:b1ce54272580 452 ControllerStatus[controller] & 0x0004 // controller starting up / settling
kotakku 0:b1ce54272580 453 ControllerStatus[controller] & 0x0008 // headset adapter plugged in, but no headphones connected (mute?)
kotakku 0:b1ce54272580 454 ControllerStatus[controller] & 0x0010 // 0
kotakku 0:b1ce54272580 455 ControllerStatus[controller] & 0x0020 // 1
kotakku 0:b1ce54272580 456 ControllerStatus[controller] & 0x0040 // battery level (high bit)
kotakku 0:b1ce54272580 457 ControllerStatus[controller] & 0x0080 // battery level (low bit)
kotakku 0:b1ce54272580 458 ControllerStatus[controller] & 0x0100 // 1
kotakku 0:b1ce54272580 459 ControllerStatus[controller] & 0x0200 // 1
kotakku 0:b1ce54272580 460 ControllerStatus[controller] & 0x0400 // headset adapter plugged in
kotakku 0:b1ce54272580 461 ControllerStatus[controller] & 0x0800 // 0
kotakku 0:b1ce54272580 462 ControllerStatus[controller] & 0x1000 // 1
kotakku 0:b1ce54272580 463 ControllerStatus[controller] & 0x2000 // 0
kotakku 0:b1ce54272580 464 ControllerStatus[controller] & 0x4000 // 0
kotakku 0:b1ce54272580 465 ControllerStatus[controller] & 0x8000 // 0
kotakku 0:b1ce54272580 466 */
kotakku 0:b1ce54272580 467 uint8_t XBOXRECV::getBatteryLevel(uint8_t controller) {
kotakku 0:b1ce54272580 468 return ((controllerStatus[controller] & 0x00C0) >> 6);
kotakku 0:b1ce54272580 469 }
kotakku 0:b1ce54272580 470
kotakku 0:b1ce54272580 471 void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) {
kotakku 0:b1ce54272580 472 #ifdef EXTRADEBUG
kotakku 0:b1ce54272580 473 uint8_t rcode;
kotakku 0:b1ce54272580 474 #endif
kotakku 0:b1ce54272580 475 uint8_t outputPipe;
kotakku 0:b1ce54272580 476 switch(controller) {
kotakku 0:b1ce54272580 477 case 0: outputPipe = XBOX_OUTPUT_PIPE_1;
kotakku 0:b1ce54272580 478 break;
kotakku 0:b1ce54272580 479 case 1: outputPipe = XBOX_OUTPUT_PIPE_2;
kotakku 0:b1ce54272580 480 break;
kotakku 0:b1ce54272580 481 case 2: outputPipe = XBOX_OUTPUT_PIPE_3;
kotakku 0:b1ce54272580 482 break;
kotakku 0:b1ce54272580 483 case 3: outputPipe = XBOX_OUTPUT_PIPE_4;
kotakku 0:b1ce54272580 484 break;
kotakku 0:b1ce54272580 485 default:
kotakku 0:b1ce54272580 486 return;
kotakku 0:b1ce54272580 487 }
kotakku 0:b1ce54272580 488 #ifdef EXTRADEBUG
kotakku 0:b1ce54272580 489 rcode =
kotakku 0:b1ce54272580 490 #endif
kotakku 0:b1ce54272580 491 pUsb->outTransfer(bAddress, epInfo[ outputPipe ].epAddr, nbytes, data);
kotakku 0:b1ce54272580 492 #ifdef EXTRADEBUG
kotakku 0:b1ce54272580 493 if(rcode)
kotakku 0:b1ce54272580 494 Notify(PSTR("Error sending Xbox message\r\n"), 0x80);
kotakku 0:b1ce54272580 495 #endif
kotakku 0:b1ce54272580 496 }
kotakku 0:b1ce54272580 497
kotakku 0:b1ce54272580 498 void XBOXRECV::disconnect(uint8_t controller) {
kotakku 0:b1ce54272580 499 writeBuf[0] = 0x00;
kotakku 0:b1ce54272580 500 writeBuf[1] = 0x00;
kotakku 0:b1ce54272580 501 writeBuf[2] = 0x08;
kotakku 0:b1ce54272580 502 writeBuf[3] = 0xC0;
kotakku 0:b1ce54272580 503
kotakku 0:b1ce54272580 504 XboxCommand(controller, writeBuf, 4);
kotakku 0:b1ce54272580 505 }
kotakku 0:b1ce54272580 506
kotakku 0:b1ce54272580 507 void XBOXRECV::setLedRaw(uint8_t value, uint8_t controller) {
kotakku 0:b1ce54272580 508 writeBuf[0] = 0x00;
kotakku 0:b1ce54272580 509 writeBuf[1] = 0x00;
kotakku 0:b1ce54272580 510 writeBuf[2] = 0x08;
kotakku 0:b1ce54272580 511 writeBuf[3] = value | 0x40;
kotakku 0:b1ce54272580 512
kotakku 0:b1ce54272580 513 XboxCommand(controller, writeBuf, 4);
kotakku 0:b1ce54272580 514 }
kotakku 0:b1ce54272580 515
kotakku 0:b1ce54272580 516 void XBOXRECV::setLedOn(LEDEnum led, uint8_t controller) {
kotakku 0:b1ce54272580 517 if(led == OFF)
kotakku 0:b1ce54272580 518 setLedRaw(0, controller);
kotakku 0:b1ce54272580 519 else if(led != ALL) // All LEDs can't be on a the same time
kotakku 0:b1ce54272580 520 setLedRaw(pgm_read_byte(&XBOX_LEDS[(uint8_t)led]) + 4, controller);
kotakku 0:b1ce54272580 521 }
kotakku 0:b1ce54272580 522
kotakku 0:b1ce54272580 523 void XBOXRECV::setLedBlink(LEDEnum led, uint8_t controller) {
kotakku 0:b1ce54272580 524 setLedRaw(pgm_read_byte(&XBOX_LEDS[(uint8_t)led]), controller);
kotakku 0:b1ce54272580 525 }
kotakku 0:b1ce54272580 526
kotakku 0:b1ce54272580 527 void XBOXRECV::setLedMode(LEDModeEnum ledMode, uint8_t controller) { // This function is used to do some speciel LED stuff the controller supports
kotakku 0:b1ce54272580 528 setLedRaw((uint8_t)ledMode, controller);
kotakku 0:b1ce54272580 529 }
kotakku 0:b1ce54272580 530
kotakku 0:b1ce54272580 531 /* PC runs this at interval of approx 2 seconds
kotakku 0:b1ce54272580 532 Thanks to BusHound from Perisoft.net for the Windows USB Analysis output
kotakku 0:b1ce54272580 533 Found by timstamp.co.uk
kotakku 0:b1ce54272580 534 */
kotakku 0:b1ce54272580 535 void XBOXRECV::checkStatus() {
kotakku 0:b1ce54272580 536 if(!bPollEnable)
kotakku 0:b1ce54272580 537 return;
kotakku 0:b1ce54272580 538 // Get controller info
kotakku 0:b1ce54272580 539 writeBuf[0] = 0x08;
kotakku 0:b1ce54272580 540 writeBuf[1] = 0x00;
kotakku 0:b1ce54272580 541 writeBuf[2] = 0x0f;
kotakku 0:b1ce54272580 542 writeBuf[3] = 0xc0;
kotakku 0:b1ce54272580 543 for(uint8_t i = 0; i < 4; i++) {
kotakku 0:b1ce54272580 544 XboxCommand(i, writeBuf, 4);
kotakku 0:b1ce54272580 545 }
kotakku 0:b1ce54272580 546 // Get battery status
kotakku 0:b1ce54272580 547 writeBuf[0] = 0x00;
kotakku 0:b1ce54272580 548 writeBuf[1] = 0x00;
kotakku 0:b1ce54272580 549 writeBuf[2] = 0x00;
kotakku 0:b1ce54272580 550 writeBuf[3] = 0x40;
kotakku 0:b1ce54272580 551 for(uint8_t i = 0; i < 4; i++) {
kotakku 0:b1ce54272580 552 if(Xbox360Connected[i])
kotakku 0:b1ce54272580 553 XboxCommand(i, writeBuf, 4);
kotakku 0:b1ce54272580 554 }
kotakku 0:b1ce54272580 555 }
kotakku 0:b1ce54272580 556
kotakku 0:b1ce54272580 557 void XBOXRECV::setRumbleOn(uint8_t lValue, uint8_t rValue, uint8_t controller) {
kotakku 0:b1ce54272580 558 writeBuf[0] = 0x00;
kotakku 0:b1ce54272580 559 writeBuf[1] = 0x01;
kotakku 0:b1ce54272580 560 writeBuf[2] = 0x0f;
kotakku 0:b1ce54272580 561 writeBuf[3] = 0xc0;
kotakku 0:b1ce54272580 562 writeBuf[4] = 0x00;
kotakku 0:b1ce54272580 563 writeBuf[5] = lValue; // big weight
kotakku 0:b1ce54272580 564 writeBuf[6] = rValue; // small weight
kotakku 0:b1ce54272580 565
kotakku 0:b1ce54272580 566 XboxCommand(controller, writeBuf, 7);
kotakku 0:b1ce54272580 567 }
kotakku 0:b1ce54272580 568
kotakku 0:b1ce54272580 569 void XBOXRECV::onInit(uint8_t controller) {
kotakku 0:b1ce54272580 570 if(pFuncOnInit)
kotakku 0:b1ce54272580 571 pFuncOnInit(); // Call the user function
kotakku 0:b1ce54272580 572 else {
kotakku 0:b1ce54272580 573 LEDEnum led;
kotakku 0:b1ce54272580 574 if(controller == 0)
kotakku 0:b1ce54272580 575 led = static_cast<LEDEnum>(CONTROLLER_LED1);
kotakku 0:b1ce54272580 576 else if(controller == 1)
kotakku 0:b1ce54272580 577 led = static_cast<LEDEnum>(CONTROLLER_LED2);
kotakku 0:b1ce54272580 578 else if(controller == 2)
kotakku 0:b1ce54272580 579 led = static_cast<LEDEnum>(CONTROLLER_LED3);
kotakku 0:b1ce54272580 580 else
kotakku 0:b1ce54272580 581 led = static_cast<LEDEnum>(CONTROLLER_LED4);
kotakku 0:b1ce54272580 582 setLedOn(led, controller);
kotakku 0:b1ce54272580 583 }
kotakku 0:b1ce54272580 584 }
kotakku 0:b1ce54272580 585