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) 2013 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
kotakku 0:b1ce54272580 18 #include "XBOXOLD.h"
kotakku 0:b1ce54272580 19 // To enable serial debugging see "settings.h"
kotakku 0:b1ce54272580 20 //#define EXTRADEBUG // Uncomment to get even more debugging data
kotakku 0:b1ce54272580 21 //#define PRINTREPORT // Uncomment to print the report send by the Xbox controller
kotakku 0:b1ce54272580 22
kotakku 0:b1ce54272580 23 /** Buttons on the controllers */
kotakku 0:b1ce54272580 24 const uint8_t XBOXOLD_BUTTONS[] PROGMEM = {
kotakku 0:b1ce54272580 25 0x01, // UP
kotakku 0:b1ce54272580 26 0x08, // RIGHT
kotakku 0:b1ce54272580 27 0x02, // DOWN
kotakku 0:b1ce54272580 28 0x04, // LEFT
kotakku 0:b1ce54272580 29
kotakku 0:b1ce54272580 30 0x20, // BACK
kotakku 0:b1ce54272580 31 0x10, // START
kotakku 0:b1ce54272580 32 0x40, // L3
kotakku 0:b1ce54272580 33 0x80, // R3
kotakku 0:b1ce54272580 34
kotakku 0:b1ce54272580 35 // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
kotakku 0:b1ce54272580 36 4, // BLACK
kotakku 0:b1ce54272580 37 5, // WHTIE
kotakku 0:b1ce54272580 38 6, // L1
kotakku 0:b1ce54272580 39 7, // R1
kotakku 0:b1ce54272580 40
kotakku 0:b1ce54272580 41 1, // B
kotakku 0:b1ce54272580 42 0, // A
kotakku 0:b1ce54272580 43 2, // X
kotakku 0:b1ce54272580 44 3, // Y
kotakku 0:b1ce54272580 45 };
kotakku 0:b1ce54272580 46
kotakku 0:b1ce54272580 47 XBOXOLD::XBOXOLD(USB *p) :
kotakku 0:b1ce54272580 48 pUsb(p), // pointer to USB class instance - mandatory
kotakku 0:b1ce54272580 49 bAddress(0), // device address - mandatory
kotakku 0:b1ce54272580 50 bPollEnable(false) { // don't start polling before dongle is connected
kotakku 0:b1ce54272580 51 for(uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
kotakku 0:b1ce54272580 52 epInfo[i].epAddr = 0;
kotakku 0:b1ce54272580 53 epInfo[i].maxPktSize = (i) ? 0 : 8;
kotakku 0:b1ce54272580 54 epInfo[i].bmSndToggle = 0;
kotakku 0:b1ce54272580 55 epInfo[i].bmRcvToggle = 0;
kotakku 0:b1ce54272580 56 epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
kotakku 0:b1ce54272580 57 }
kotakku 0:b1ce54272580 58
kotakku 0:b1ce54272580 59 if(pUsb) // register in USB subsystem
kotakku 0:b1ce54272580 60 pUsb->RegisterDeviceClass(this); //set devConfig[] entry
kotakku 0:b1ce54272580 61 }
kotakku 0:b1ce54272580 62
kotakku 0:b1ce54272580 63 uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
kotakku 0:b1ce54272580 64 uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
kotakku 0:b1ce54272580 65 USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
kotakku 0:b1ce54272580 66 uint8_t rcode;
kotakku 0:b1ce54272580 67 UsbDevice *p = NULL;
kotakku 0:b1ce54272580 68 EpInfo *oldep_ptr = NULL;
kotakku 0:b1ce54272580 69 uint16_t PID;
kotakku 0:b1ce54272580 70 uint16_t VID;
kotakku 0:b1ce54272580 71
kotakku 0:b1ce54272580 72 // get memory address of USB device address pool
kotakku 0:b1ce54272580 73 AddressPool &addrPool = pUsb->GetAddressPool();
kotakku 0:b1ce54272580 74 #ifdef EXTRADEBUG
kotakku 0:b1ce54272580 75 Notify(PSTR("\r\nXBOXUSB Init"), 0x80);
kotakku 0:b1ce54272580 76 #endif
kotakku 0:b1ce54272580 77 // check if address has already been assigned to an instance
kotakku 0:b1ce54272580 78 if(bAddress) {
kotakku 0:b1ce54272580 79 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 80 Notify(PSTR("\r\nAddress in use"), 0x80);
kotakku 0:b1ce54272580 81 #endif
kotakku 0:b1ce54272580 82 return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
kotakku 0:b1ce54272580 83 }
kotakku 0:b1ce54272580 84
kotakku 0:b1ce54272580 85 // Get pointer to pseudo device with address 0 assigned
kotakku 0:b1ce54272580 86 p = addrPool.GetUsbDevicePtr(0);
kotakku 0:b1ce54272580 87
kotakku 0:b1ce54272580 88 if(!p) {
kotakku 0:b1ce54272580 89 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 90 Notify(PSTR("\r\nAddress not found"), 0x80);
kotakku 0:b1ce54272580 91 #endif
kotakku 0:b1ce54272580 92 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
kotakku 0:b1ce54272580 93 }
kotakku 0:b1ce54272580 94
kotakku 0:b1ce54272580 95 if(!p->epinfo) {
kotakku 0:b1ce54272580 96 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 97 Notify(PSTR("\r\nepinfo is null"), 0x80);
kotakku 0:b1ce54272580 98 #endif
kotakku 0:b1ce54272580 99 return USB_ERROR_EPINFO_IS_NULL;
kotakku 0:b1ce54272580 100 }
kotakku 0:b1ce54272580 101
kotakku 0:b1ce54272580 102 // Save old pointer to EP_RECORD of address 0
kotakku 0:b1ce54272580 103 oldep_ptr = p->epinfo;
kotakku 0:b1ce54272580 104
kotakku 0:b1ce54272580 105 // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
kotakku 0:b1ce54272580 106 p->epinfo = epInfo;
kotakku 0:b1ce54272580 107
kotakku 0:b1ce54272580 108 p->lowspeed = lowspeed;
kotakku 0:b1ce54272580 109
kotakku 0:b1ce54272580 110 // Get device descriptor
kotakku 0:b1ce54272580 111 rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
kotakku 0:b1ce54272580 112 // Restore p->epinfo
kotakku 0:b1ce54272580 113 p->epinfo = oldep_ptr;
kotakku 0:b1ce54272580 114
kotakku 0:b1ce54272580 115 if(rcode)
kotakku 0:b1ce54272580 116 goto FailGetDevDescr;
kotakku 0:b1ce54272580 117
kotakku 0:b1ce54272580 118 VID = udd->idVendor;
kotakku 0:b1ce54272580 119 PID = udd->idProduct;
kotakku 0:b1ce54272580 120
kotakku 0:b1ce54272580 121 if((VID != XBOX_VID && VID != MADCATZ_VID && VID != JOYTECH_VID) || (PID != XBOX_OLD_PID1 && PID != XBOX_OLD_PID2 && PID != XBOX_OLD_PID3 && PID != XBOX_OLD_PID4)) // Check if VID and PID match
kotakku 0:b1ce54272580 122 goto FailUnknownDevice;
kotakku 0:b1ce54272580 123
kotakku 0:b1ce54272580 124 // Allocate new address according to device class
kotakku 0:b1ce54272580 125 bAddress = addrPool.AllocAddress(parent, false, port);
kotakku 0:b1ce54272580 126
kotakku 0:b1ce54272580 127 if(!bAddress)
kotakku 0:b1ce54272580 128 return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
kotakku 0:b1ce54272580 129
kotakku 0:b1ce54272580 130 // Extract Max Packet Size from device descriptor
kotakku 0:b1ce54272580 131 epInfo[0].maxPktSize = udd->bMaxPacketSize0;
kotakku 0:b1ce54272580 132
kotakku 0:b1ce54272580 133 // Assign new address to the device
kotakku 0:b1ce54272580 134 rcode = pUsb->setAddr(0, 0, bAddress);
kotakku 0:b1ce54272580 135 if(rcode) {
kotakku 0:b1ce54272580 136 p->lowspeed = false;
kotakku 0:b1ce54272580 137 addrPool.FreeAddress(bAddress);
kotakku 0:b1ce54272580 138 bAddress = 0;
kotakku 0:b1ce54272580 139 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 140 Notify(PSTR("\r\nsetAddr: "), 0x80);
kotakku 0:b1ce54272580 141 D_PrintHex<uint8_t > (rcode, 0x80);
kotakku 0:b1ce54272580 142 #endif
kotakku 0:b1ce54272580 143 return rcode;
kotakku 0:b1ce54272580 144 }
kotakku 0:b1ce54272580 145 #ifdef EXTRADEBUG
kotakku 0:b1ce54272580 146 Notify(PSTR("\r\nAddr: "), 0x80);
kotakku 0:b1ce54272580 147 D_PrintHex<uint8_t > (bAddress, 0x80);
kotakku 0:b1ce54272580 148 #endif
kotakku 0:b1ce54272580 149 //delay(300); // Spec says you should wait at least 200ms
kotakku 0:b1ce54272580 150
kotakku 0:b1ce54272580 151 p->lowspeed = false;
kotakku 0:b1ce54272580 152
kotakku 0:b1ce54272580 153 //get pointer to assigned address record
kotakku 0:b1ce54272580 154 p = addrPool.GetUsbDevicePtr(bAddress);
kotakku 0:b1ce54272580 155 if(!p)
kotakku 0:b1ce54272580 156 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
kotakku 0:b1ce54272580 157
kotakku 0:b1ce54272580 158 p->lowspeed = lowspeed;
kotakku 0:b1ce54272580 159
kotakku 0:b1ce54272580 160 // Assign epInfo to epinfo pointer - only EP0 is known
kotakku 0:b1ce54272580 161 rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
kotakku 0:b1ce54272580 162 if(rcode)
kotakku 0:b1ce54272580 163 goto FailSetDevTblEntry;
kotakku 0:b1ce54272580 164
kotakku 0:b1ce54272580 165 /* The application will work in reduced host mode, so we can save program and data
kotakku 0:b1ce54272580 166 memory space. After verifying the VID we will use known values for the
kotakku 0:b1ce54272580 167 configuration values for device, interface, endpoints and HID for the XBOX controllers */
kotakku 0:b1ce54272580 168
kotakku 0:b1ce54272580 169 /* Initialize data structures for endpoints of device */
kotakku 0:b1ce54272580 170 epInfo[ XBOX_INPUT_PIPE ].epAddr = 0x01; // XBOX report endpoint
kotakku 0:b1ce54272580 171 epInfo[ XBOX_INPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
kotakku 0:b1ce54272580 172 epInfo[ XBOX_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
kotakku 0:b1ce54272580 173 epInfo[ XBOX_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
kotakku 0:b1ce54272580 174 epInfo[ XBOX_INPUT_PIPE ].bmSndToggle = 0;
kotakku 0:b1ce54272580 175 epInfo[ XBOX_INPUT_PIPE ].bmRcvToggle = 0;
kotakku 0:b1ce54272580 176 epInfo[ XBOX_OUTPUT_PIPE ].epAddr = 0x02; // XBOX output endpoint
kotakku 0:b1ce54272580 177 epInfo[ XBOX_OUTPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
kotakku 0:b1ce54272580 178 epInfo[ XBOX_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
kotakku 0:b1ce54272580 179 epInfo[ XBOX_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
kotakku 0:b1ce54272580 180 epInfo[ XBOX_OUTPUT_PIPE ].bmSndToggle = 0;
kotakku 0:b1ce54272580 181 epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = 0;
kotakku 0:b1ce54272580 182
kotakku 0:b1ce54272580 183 rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
kotakku 0:b1ce54272580 184 if(rcode)
kotakku 0:b1ce54272580 185 goto FailSetDevTblEntry;
kotakku 0:b1ce54272580 186
kotakku 0:b1ce54272580 187 delay(200); // Give time for address change
kotakku 0:b1ce54272580 188
kotakku 0:b1ce54272580 189 rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
kotakku 0:b1ce54272580 190 if(rcode)
kotakku 0:b1ce54272580 191 goto FailSetConfDescr;
kotakku 0:b1ce54272580 192
kotakku 0:b1ce54272580 193 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 194 Notify(PSTR("\r\nXbox Controller Connected\r\n"), 0x80);
kotakku 0:b1ce54272580 195 #endif
kotakku 0:b1ce54272580 196 if(pFuncOnInit)
kotakku 0:b1ce54272580 197 pFuncOnInit(); // Call the user function
kotakku 0:b1ce54272580 198 XboxConnected = true;
kotakku 0:b1ce54272580 199 bPollEnable = true;
kotakku 0:b1ce54272580 200 return 0; // Successful configuration
kotakku 0:b1ce54272580 201
kotakku 0:b1ce54272580 202 /* Diagnostic messages */
kotakku 0:b1ce54272580 203 FailGetDevDescr:
kotakku 0:b1ce54272580 204 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 205 NotifyFailGetDevDescr();
kotakku 0:b1ce54272580 206 goto Fail;
kotakku 0:b1ce54272580 207 #endif
kotakku 0:b1ce54272580 208
kotakku 0:b1ce54272580 209 FailSetDevTblEntry:
kotakku 0:b1ce54272580 210 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 211 NotifyFailSetDevTblEntry();
kotakku 0:b1ce54272580 212 goto Fail;
kotakku 0:b1ce54272580 213 #endif
kotakku 0:b1ce54272580 214
kotakku 0:b1ce54272580 215 FailSetConfDescr:
kotakku 0:b1ce54272580 216 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 217 NotifyFailSetConfDescr();
kotakku 0:b1ce54272580 218 #endif
kotakku 0:b1ce54272580 219 goto Fail;
kotakku 0:b1ce54272580 220
kotakku 0:b1ce54272580 221 FailUnknownDevice:
kotakku 0:b1ce54272580 222 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 223 NotifyFailUnknownDevice(VID, PID);
kotakku 0:b1ce54272580 224 #endif
kotakku 0:b1ce54272580 225 rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
kotakku 0:b1ce54272580 226
kotakku 0:b1ce54272580 227 Fail:
kotakku 0:b1ce54272580 228 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 229 Notify(PSTR("\r\nXbox Init Failed, error code: "), 0x80);
kotakku 0:b1ce54272580 230 NotifyFail(rcode);
kotakku 0:b1ce54272580 231 #endif
kotakku 0:b1ce54272580 232 Release();
kotakku 0:b1ce54272580 233 return rcode;
kotakku 0:b1ce54272580 234 }
kotakku 0:b1ce54272580 235
kotakku 0:b1ce54272580 236 /* Performs a cleanup after failed Init() attempt */
kotakku 0:b1ce54272580 237 uint8_t XBOXOLD::Release() {
kotakku 0:b1ce54272580 238 XboxConnected = false;
kotakku 0:b1ce54272580 239 pUsb->GetAddressPool().FreeAddress(bAddress);
kotakku 0:b1ce54272580 240 bAddress = 0;
kotakku 0:b1ce54272580 241 bPollEnable = false;
kotakku 0:b1ce54272580 242 return 0;
kotakku 0:b1ce54272580 243 }
kotakku 0:b1ce54272580 244
kotakku 0:b1ce54272580 245 uint8_t XBOXOLD::Poll() {
kotakku 0:b1ce54272580 246 if(!bPollEnable)
kotakku 0:b1ce54272580 247 return 0;
kotakku 0:b1ce54272580 248 uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
kotakku 0:b1ce54272580 249 pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
kotakku 0:b1ce54272580 250 readReport();
kotakku 0:b1ce54272580 251 #ifdef PRINTREPORT
kotakku 0:b1ce54272580 252 printReport(BUFFER_SIZE); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox controller
kotakku 0:b1ce54272580 253 #endif
kotakku 0:b1ce54272580 254 return 0;
kotakku 0:b1ce54272580 255 }
kotakku 0:b1ce54272580 256
kotakku 0:b1ce54272580 257 void XBOXOLD::readReport() {
kotakku 0:b1ce54272580 258 ButtonState = readBuf[2];
kotakku 0:b1ce54272580 259
kotakku 0:b1ce54272580 260 for(uint8_t i = 0; i < sizeof (buttonValues); i++)
kotakku 0:b1ce54272580 261 buttonValues[i] = readBuf[i + 4]; // A, B, X, Y, BLACK, WHITE, L1, and R1
kotakku 0:b1ce54272580 262
kotakku 0:b1ce54272580 263 hatValue[LeftHatX] = (int16_t)(((uint16_t)readBuf[12] << 8) | readBuf[13]);
kotakku 0:b1ce54272580 264 hatValue[LeftHatY] = (int16_t)(((uint16_t)readBuf[14] << 8) | readBuf[15]);
kotakku 0:b1ce54272580 265 hatValue[RightHatX] = (int16_t)(((uint16_t)readBuf[16] << 8) | readBuf[17]);
kotakku 0:b1ce54272580 266 hatValue[RightHatY] = (int16_t)(((uint16_t)readBuf[18] << 8) | readBuf[19]);
kotakku 0:b1ce54272580 267
kotakku 0:b1ce54272580 268 //Notify(PSTR("\r\nButtonState"), 0x80);
kotakku 0:b1ce54272580 269 //PrintHex<uint8_t>(ButtonState, 0x80);
kotakku 0:b1ce54272580 270
kotakku 0:b1ce54272580 271 if(ButtonState != OldButtonState || memcmp(buttonValues, oldButtonValues, sizeof (buttonValues)) != 0) {
kotakku 0:b1ce54272580 272 ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
kotakku 0:b1ce54272580 273 OldButtonState = ButtonState;
kotakku 0:b1ce54272580 274
kotakku 0:b1ce54272580 275 for(uint8_t i = 0; i < sizeof (buttonValues); i++) {
kotakku 0:b1ce54272580 276 if(oldButtonValues[i] == 0 && buttonValues[i] != 0)
kotakku 0:b1ce54272580 277 buttonClicked[i] = true; // Update A, B, X, Y, BLACK, WHITE, L1, and R1 click state
kotakku 0:b1ce54272580 278 oldButtonValues[i] = buttonValues[i];
kotakku 0:b1ce54272580 279 }
kotakku 0:b1ce54272580 280 }
kotakku 0:b1ce54272580 281 }
kotakku 0:b1ce54272580 282
kotakku 0:b1ce54272580 283 void XBOXOLD::printReport(uint16_t length __attribute__((unused))) { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox controller
kotakku 0:b1ce54272580 284 #ifdef PRINTREPORT
kotakku 0:b1ce54272580 285 if(readBuf == NULL)
kotakku 0:b1ce54272580 286 return;
kotakku 0:b1ce54272580 287 for(uint8_t i = 0; i < length; i++) {
kotakku 0:b1ce54272580 288 D_PrintHex<uint8_t > (readBuf[i], 0x80);
kotakku 0:b1ce54272580 289 Notify(PSTR(" "), 0x80);
kotakku 0:b1ce54272580 290 }
kotakku 0:b1ce54272580 291 Notify(PSTR("\r\n"), 0x80);
kotakku 0:b1ce54272580 292 #endif
kotakku 0:b1ce54272580 293 }
kotakku 0:b1ce54272580 294
kotakku 0:b1ce54272580 295 uint8_t XBOXOLD::getButtonPress(ButtonEnum b) {
kotakku 0:b1ce54272580 296 uint8_t button = pgm_read_byte(&XBOXOLD_BUTTONS[(uint8_t)b]);
kotakku 0:b1ce54272580 297 if(b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
kotakku 0:b1ce54272580 298 return buttonValues[button]; // Analog buttons
kotakku 0:b1ce54272580 299 return (ButtonState & button); // Digital buttons
kotakku 0:b1ce54272580 300 }
kotakku 0:b1ce54272580 301
kotakku 0:b1ce54272580 302 bool XBOXOLD::getButtonClick(ButtonEnum b) {
kotakku 0:b1ce54272580 303 uint8_t button = pgm_read_byte(&XBOXOLD_BUTTONS[(uint8_t)b]);
kotakku 0:b1ce54272580 304 if(b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) { // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
kotakku 0:b1ce54272580 305 if(buttonClicked[button]) {
kotakku 0:b1ce54272580 306 buttonClicked[button] = false;
kotakku 0:b1ce54272580 307 return true;
kotakku 0:b1ce54272580 308 }
kotakku 0:b1ce54272580 309 return false;
kotakku 0:b1ce54272580 310 }
kotakku 0:b1ce54272580 311
kotakku 0:b1ce54272580 312 bool click = (ButtonClickState & button);
kotakku 0:b1ce54272580 313 ButtonClickState &= ~button; // clear "click" event
kotakku 0:b1ce54272580 314 return click;
kotakku 0:b1ce54272580 315 }
kotakku 0:b1ce54272580 316
kotakku 0:b1ce54272580 317 int16_t XBOXOLD::getAnalogHat(AnalogHatEnum a) {
kotakku 0:b1ce54272580 318 return hatValue[a];
kotakku 0:b1ce54272580 319 }
kotakku 0:b1ce54272580 320
kotakku 0:b1ce54272580 321 /* Xbox Controller commands */
kotakku 0:b1ce54272580 322 void XBOXOLD::XboxCommand(uint8_t* data, uint16_t nbytes) {
kotakku 0:b1ce54272580 323 //bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x00), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
kotakku 0:b1ce54272580 324 pUsb->ctrlReq(bAddress, epInfo[XBOX_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
kotakku 0:b1ce54272580 325 }
kotakku 0:b1ce54272580 326
kotakku 0:b1ce54272580 327 void XBOXOLD::setRumbleOn(uint8_t lValue, uint8_t rValue) {
kotakku 0:b1ce54272580 328 uint8_t writeBuf[6];
kotakku 0:b1ce54272580 329
kotakku 0:b1ce54272580 330 writeBuf[0] = 0x00;
kotakku 0:b1ce54272580 331 writeBuf[1] = 0x06;
kotakku 0:b1ce54272580 332 writeBuf[2] = 0x00;
kotakku 0:b1ce54272580 333 writeBuf[3] = rValue; // small weight
kotakku 0:b1ce54272580 334 writeBuf[4] = 0x00;
kotakku 0:b1ce54272580 335 writeBuf[5] = lValue; // big weight
kotakku 0:b1ce54272580 336
kotakku 0:b1ce54272580 337 XboxCommand(writeBuf, 6);
kotakku 0:b1ce54272580 338 }
kotakku 0:b1ce54272580 339