Suga Koubou 製 PS_PADライブラリ https://developer.mbed.org/users/okini3939/code/PS_PAD/ を改造したもの。単に__rbitが使えなかったので置き換えただけ。

Dependents:   pscontroller project_beta

Fork of PS_PAD by Suga koubou

PS_PAD.cpp

Committer:
okini3939
Date:
2013-12-11
Revision:
0:6eeefcf5a37a
Child:
1:840370e1dcce

File content as of revision 0:6eeefcf5a37a:

/*
 * PlayStation Controller library
 * Copyright (c) 2013 Hiroshi Suga
 */

#include "PS_PAD.h"

PS_PAD::PS_PAD (PinName mosi, PinName miso, PinName sck, PinName cs) : _spi(mosi, miso, sck), _cs(cs) {
    _spi.format(8, 3);
    _spi.frequency(250000);
    _cs = 1;
    _vib1 = 0;
    _vib2 = 0;
}

PS_PAD::PS_PAD (SPI &spi, PinName cs) : _spi(spi), _cs(cs) {
    _spi.format(8, 3);
    _spi.frequency(250000);
    _cs = 1;
    _vib1 = 0;
    _vib2 = 0;
}

int PS_PAD::init () {
    const char enter_config_mode[5]  = {0x01, 0x43, 0x00, 0x01, 0x00};
    const char enable_analog_mode[9] = {0x01, 0x44, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00};
    const char enable_vibration[9]   = {0x01, 0x4d, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff};
    const char exit_config_mode[9]   = {0x01, 0x43, 0x00, 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A};
    char buf[10];
 
    send(enter_config_mode, 5, buf);
    if (buf[2] == 0xff) {
        return -1;
    }
    wait_ms(16);
    send(enable_analog_mode, 9, buf);
    wait_ms(16);
    send(enable_vibration, 9, buf);
    wait_ms(16);
    send(exit_config_mode, 9, buf);
    wait_ms(16);
    return 0;
}

int PS_PAD::poll () {
    const char poll_command[9] = {0x01, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    int i;
    char cmd[10], buf[10];

    memcpy(cmd, poll_command, 9);
    cmd[3] = _vib1;
    cmd[4] = _vib2;
    send(cmd, 9, buf);
    if (buf[2] == 0xff) {
        return -1;
    }

    for (i = 0; i < 6; i ++) {
        _pad[i] = buf[3 + i];
    }
    return 0;
}

int PS_PAD::read (TYPE t) {
    switch (t) {
    case PAD_LEFT:
        return _pad[0] & 0x80 ? 0 : 1;
    case PAD_BOTTOM:
        return _pad[0] & 0x40 ? 0 : 1;
    case PAD_RIGHT:
        return _pad[0] & 0x20 ? 0 : 1;
    case PAD_TOP:
        return _pad[0] & 0x10 ? 0 : 1;
    case PAD_START:
        return _pad[0] & 0x08 ? 0 : 1;
    case ANALOG_LEFT:
        return _pad[0] & 0x04 ? 0 : 1;
    case ANALOG_RIGHT:
        return _pad[0] & 0x02 ? 0 : 1;
    case PAD_SELECT:
        return _pad[0] & 0x01 ? 0 : 1;
    case PAD_SQUARE:
        return _pad[1] & 0x80 ? 0 : 1;
    case PAD_X:
        return _pad[1] & 0x40 ? 0 : 1;
    case PAD_CIRCLE:
        return _pad[1] & 0x20 ? 0 : 1;
    case PAD_TRIANGLE:
        return _pad[1] & 0x10 ? 0 : 1;
    case PAD_R1:
        return _pad[1] & 0x08 ? 0 : 1;
    case PAD_L1:
        return _pad[1] & 0x04 ? 0 : 1;
    case PAD_R2:
        return _pad[1] & 0x02 ? 0 : 1;
    case PAD_L2:
        return _pad[1] & 0x01 ? 0 : 1;
    case ANALOG_RX:
        if (_pad[2] < 0x80) {
            return (_pad[2] - 0x7f) * 100 / 0x7f;
        } else {
            return (_pad[2] - 0x7f) * 100 / 0x7f;
        }
    case ANALOG_RY:
        if (_pad[3] < 0x80) {
            return (_pad[3] - 0x7f) * 100 / 0x7f;
        } else {
            return (_pad[3] - 0x7f) * 100 / 0x7f;
        }
    case ANALOG_LX:
        if (_pad[4] < 0x80) {
            return (_pad[4] - 0x7f) * 100 / 0x7f;
        } else {
            return (_pad[4] - 0x7f) * 100 / 0x7f;
        }
    case ANALOG_LY:
        if (_pad[5] < 0x80) {
            return (_pad[5] - 0x7f) * 100 / 0x7f;
        } else {
            return (_pad[5] - 0x7f) * 100 / 0x7f;
        }
    }
    return 0;
}

int PS_PAD::vibration (int v1, int v2) {
    _vib1 = v1 ? 1 : 0;
    if (v2 < 0) v2 = 0;
    if (v2 > 0xff) v2 = 0;
    _vib2 = v2;
    poll();
    return 0;
}

int PS_PAD::send (const char *cmd, int len, char *dat) {
    int i;

    _cs = 0;
    wait_us(10);
    for (i = 0; i < len; i ++) {
        dat[i] = __rbit(_spi.write(__rbit(cmd[i] << 24)) << 24);
        wait_us(10);
    }
    _cs = 1;
    return i;
}