N64 on Esp32 works perfectly now
This commit is contained in:
parent
3146ebec3a
commit
edc283a9ae
|
@ -164,7 +164,7 @@ build_flags = ${in-snes.build_flags} ${out-switchusb.build_flags}
|
|||
|
||||
[in-n64-esp32]
|
||||
src_filter = -<*> +<N64Esp32.cpp>
|
||||
build_flags = ${common.build_flags} -DGAMEPAD_INPUT=3 -DGAMEPAD_COUNT=1 -fpermissive -O0
|
||||
build_flags = ${common.build_flags} -DGAMEPAD_INPUT=3 -DGAMEPAD_COUNT=1
|
||||
|
||||
[in-n64-micro]
|
||||
src_filter = -<*> +<N64Micro.cpp>
|
||||
|
|
306
src/N64Esp32.cpp
306
src/N64Esp32.cpp
|
@ -16,21 +16,21 @@ PIN # USAGE
|
|||
|
||||
#include "pins.h"
|
||||
|
||||
#define DATA_PIN 23
|
||||
#define DATA_PIN OR_PIN_2
|
||||
|
||||
//#define PRINT_Y_AXIS_VALUES 1
|
||||
//#define PRINT_X_AXIS_VALUES 1
|
||||
//#define PLOT_CONSOLE_POLLING 1
|
||||
#define DEBUG
|
||||
#define PRINT_DATA
|
||||
//#define DEBUG
|
||||
//#define PRINT_DATA
|
||||
|
||||
#ifndef GAMEPAD_COUNT
|
||||
#define GAMEPAD_COUNT 1
|
||||
#endif
|
||||
|
||||
#define AXIS_CENTER_IN 0
|
||||
#define AXIS_MAX_IN 60
|
||||
#define AXIS_MIN_IN -60
|
||||
#define AXIS_MAX_IN 70
|
||||
#define AXIS_MIN_IN -70
|
||||
|
||||
#include "gamepad/Gamepad.h"
|
||||
#include "util.cpp"
|
||||
|
@ -38,10 +38,7 @@ PIN # USAGE
|
|||
#define LINE_WRITE_HIGH pinMode(DATA_PIN, INPUT_PULLUP)
|
||||
#define LINE_WRITE_LOW pinMode(DATA_PIN, OUTPUT)
|
||||
|
||||
#define MAX_INCLINE_AXIS_X 60
|
||||
#define MAX_INCLINE_AXIS_Y 60
|
||||
|
||||
#define DATA_SIZE 1536 // number of sample points to poll
|
||||
#define DATA_SIZE 2048 // number of sample points to poll
|
||||
#define CALIBRATE_PASSES 5
|
||||
|
||||
#define NUM_BITS 32
|
||||
|
@ -49,10 +46,12 @@ PIN # USAGE
|
|||
// buffer to hold data being read from controller
|
||||
bool buffer[DATA_SIZE];
|
||||
|
||||
// bit resolution and offsets
|
||||
int bitOffsets[NUM_BITS];
|
||||
// bit resolution
|
||||
int bitResolution = 0;
|
||||
int bitsToRead = DATA_SIZE;
|
||||
int lastIndex = 0;
|
||||
|
||||
bool returnedBits[NUM_BITS];
|
||||
bool oldReport[NUM_BITS];
|
||||
|
||||
GAMEPAD_CLASS gamepad;
|
||||
|
||||
|
@ -91,10 +90,7 @@ void updateOffsetsAndResolution() {
|
|||
// current index
|
||||
int i = 0;
|
||||
|
||||
// we might be further refining a previous calibration, if non-zero, remove existing bitResolution
|
||||
for (int i = 0; i < NUM_BITS; i++) {
|
||||
bitOffsets[i] += bitResolution;
|
||||
}
|
||||
bitResolution /= 2;
|
||||
|
||||
for (; i < DATA_SIZE; i++) {
|
||||
if (buffer[i] == false) {
|
||||
|
@ -110,9 +106,8 @@ void updateOffsetsAndResolution() {
|
|||
// if a falling edge is detected
|
||||
if (buffer[1 + i] == false) {
|
||||
// store bit's earliest possible beginning offsets
|
||||
int thisOffset = i - thisResolution + 1;
|
||||
if (bitOffsets[bitCounter] == 0 || bitOffsets[bitCounter] > thisOffset) {
|
||||
bitOffsets[bitCounter] = thisOffset;
|
||||
if (lastIndex < (i + 1)) {
|
||||
lastIndex = i + 1;
|
||||
}
|
||||
|
||||
// store max resolution in bitResolution
|
||||
|
@ -128,17 +123,12 @@ void updateOffsetsAndResolution() {
|
|||
}
|
||||
}
|
||||
|
||||
// calculate bit's beginning offsets by subtracting resolution
|
||||
// if this index is 0, button is not pressed, if 1, button is pressed
|
||||
for (int i = 0; i < NUM_BITS; i++) {
|
||||
bitOffsets[i] -= bitResolution;
|
||||
}
|
||||
bitResolution *= 2;
|
||||
}
|
||||
|
||||
void calcBitsToRead() {
|
||||
bitsToRead = bitOffsets[NUM_BITS - 1] + 1;
|
||||
if (bitsToRead < NUM_BITS * 2) {
|
||||
// todo: not enough, error out...
|
||||
void checkBitsToRead() {
|
||||
if (lastIndex < NUM_BITS * 2) {
|
||||
// not enough, error out...
|
||||
while (true) {
|
||||
printf("not enough bitsToRead, increase DATA_SIZE ???\n");
|
||||
delay(5000);
|
||||
|
@ -146,11 +136,6 @@ void calcBitsToRead() {
|
|||
}
|
||||
}
|
||||
|
||||
/* Function to extract a controller bit from the buffer of returned data */
|
||||
void getBit(bool *bit, int offset, bool *data) {
|
||||
*bit = data[offset] == true;
|
||||
}
|
||||
|
||||
/** Function to send a Command to the attached N64-Controller.
|
||||
* Must be run from RAM to defy timing differences introduced from
|
||||
* reading Code from ESP32's SPI Flash Chip.
|
||||
|
@ -159,9 +144,6 @@ void IRAM_ATTR sendCommand(byte command) {
|
|||
// the current bit to write
|
||||
bool bit;
|
||||
|
||||
// clear output buffer, todo: really need to do this????
|
||||
//memset(buffer, 0, DATA_SIZE);
|
||||
|
||||
noInterrupts();
|
||||
|
||||
// for each bit
|
||||
|
@ -180,12 +162,13 @@ void IRAM_ATTR sendCommand(byte command) {
|
|||
LINE_WRITE_LOW;
|
||||
delayMicroseconds(1);
|
||||
LINE_WRITE_HIGH;
|
||||
delayMicroseconds(2);
|
||||
delayMicroseconds(1); // by spec should be 2
|
||||
|
||||
// read returned data as fast as possible
|
||||
for (int i = 0; i < bitsToRead; i++) {
|
||||
//buffer[i] = digitalRead(DATA_PIN);
|
||||
for (int i = 0; i < DATA_SIZE; i++) {
|
||||
// this is faster:
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
|
||||
#if DATA_PIN < 32
|
||||
buffer[i] = (GPIO.in >> DATA_PIN) & 0x1;
|
||||
#elif DATA_PIN < 40
|
||||
|
@ -195,27 +178,79 @@ void IRAM_ATTR sendCommand(byte command) {
|
|||
#error unsupported DATA_PIN must be <40
|
||||
|
||||
#endif
|
||||
//delayMicroseconds(1);
|
||||
|
||||
#else
|
||||
// this is portable:
|
||||
buffer[i] = digitalRead(DATA_PIN);
|
||||
#endif // not defined(ARDUINO_ARCH_ESP32)
|
||||
}
|
||||
|
||||
interrupts();
|
||||
|
||||
// plot polling process from controller if unstructed to
|
||||
#ifdef PLOT_CONSOLE_POLLING
|
||||
for (int i = 0; i < bitsToRead; i++) {
|
||||
for (int i = 0; i < DATA_SIZE; i++) {
|
||||
Serial.println(buffer[i] * 2500);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef PRINT_DATA
|
||||
for (int i = 0; i < bitsToRead; i++) {
|
||||
for (int i = 0; i < DATA_SIZE; i++) {
|
||||
printf(buffer[i] ? "1" : "0");
|
||||
}
|
||||
printf("\n----------------\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool calcReturnedBits() {
|
||||
// the current bit counter
|
||||
int bitCounter = 0;
|
||||
|
||||
// to hold the number of 1's in this bit
|
||||
int thisResolution = 0;
|
||||
|
||||
// current index
|
||||
int i = 0;
|
||||
for (; i < DATA_SIZE; i++) {
|
||||
if (buffer[i] == false) {
|
||||
// we skip all leading 1's
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// iterate over buffer
|
||||
for (; i < DATA_SIZE - 1 && bitCounter < NUM_BITS; i++) {
|
||||
if (buffer[i] == true) {
|
||||
++thisResolution;
|
||||
// if a falling edge is detected
|
||||
if (buffer[1 + i] == false) {
|
||||
returnedBits[bitCounter] = thisResolution >= bitResolution;
|
||||
|
||||
// reset thisResolution
|
||||
thisResolution = 0;
|
||||
// increment bitCounter
|
||||
++bitCounter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (bitCounter != 32) {
|
||||
printf("%i != 32, not enough bitsToRead, increase DATA_SIZE ???\n", bitCounter);
|
||||
// not enough, error out...
|
||||
/*
|
||||
for (int i = 0; i < bitsToRead; i++) {
|
||||
printf(buffer[i] ? "1" : "0");
|
||||
}
|
||||
printf("\n----------------\n");
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
return bitCounter == 32;
|
||||
}
|
||||
|
||||
/** Function to populate the controller struct if command 0x01 was sent.
|
||||
* Buttons are set according to data in buffer, raw axis data is written,
|
||||
* Axis Data is correctly decoded from raw axis data by taking two's complement
|
||||
|
@ -224,41 +259,29 @@ void IRAM_ATTR sendCommand(byte command) {
|
|||
*/
|
||||
void populateControllerStruct(ControllerData *data) {
|
||||
// first byte
|
||||
data->buttonA = buffer[bitOffsets[0]];
|
||||
data->buttonB = buffer[bitOffsets[1]];
|
||||
data->buttonZ = buffer[bitOffsets[2]];
|
||||
data->buttonStart = buffer[bitOffsets[3]];
|
||||
data->DPadUp = buffer[bitOffsets[4]];
|
||||
data->DPadDown = buffer[bitOffsets[5]];
|
||||
data->DPadLeft = buffer[bitOffsets[6]];
|
||||
data->DPadRight = buffer[bitOffsets[7]];
|
||||
data->buttonA = returnedBits[0];
|
||||
data->buttonB = returnedBits[1];
|
||||
data->buttonZ = returnedBits[2];
|
||||
data->buttonStart = returnedBits[3];
|
||||
data->DPadUp = returnedBits[4];
|
||||
data->DPadDown = returnedBits[5];
|
||||
data->DPadLeft = returnedBits[6];
|
||||
data->DPadRight = returnedBits[7];
|
||||
|
||||
// second byte, first two bits are unused
|
||||
data->buttonL = buffer[bitOffsets[10]];
|
||||
data->buttonR = buffer[bitOffsets[11]];
|
||||
data->CUp = buffer[bitOffsets[12]];
|
||||
data->CDown = buffer[bitOffsets[13]];
|
||||
data->CRight = buffer[bitOffsets[14]];
|
||||
data->buttonL = returnedBits[10];
|
||||
data->buttonR = returnedBits[11];
|
||||
data->CUp = returnedBits[12];
|
||||
data->CDown = returnedBits[13];
|
||||
data->CLeft = returnedBits[14];
|
||||
data->CRight = returnedBits[15];
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
// third byte
|
||||
getBit(&(data->xAxisRaw[0]), bitOffsets[16], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[1]), bitOffsets[17], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[2]), bitOffsets[18], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[3]), bitOffsets[19], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[4]), bitOffsets[20], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[5]), bitOffsets[21], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[6]), bitOffsets[22], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[7]), bitOffsets[23], &buffer[0]);
|
||||
|
||||
data->xAxisRaw[i] = returnedBits[i + 16];
|
||||
// fourth byte
|
||||
getBit(&(data->yAxisRaw[0]), bitOffsets[24], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[1]), bitOffsets[25], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[2]), bitOffsets[26], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[3]), bitOffsets[27], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[4]), bitOffsets[28], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[5]), bitOffsets[29], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[6]), bitOffsets[30], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[7]), bitOffsets[31], &buffer[0]);
|
||||
data->yAxisRaw[i] = returnedBits[i + 24];
|
||||
}
|
||||
|
||||
// sum up bits to get axis bytes
|
||||
data->xAxis = 0;
|
||||
|
@ -302,38 +325,72 @@ void populateControllerStruct(ControllerData *data) {
|
|||
}
|
||||
|
||||
// keep x axis below maxIncline
|
||||
if (data->xAxis > MAX_INCLINE_AXIS_X)
|
||||
data->xAxis = MAX_INCLINE_AXIS_X;
|
||||
if (data->xAxis < -MAX_INCLINE_AXIS_X)
|
||||
data->xAxis = -MAX_INCLINE_AXIS_X;
|
||||
if (data->xAxis > AXIS_MAX_IN)
|
||||
data->xAxis = AXIS_MAX_IN;
|
||||
if (data->xAxis < AXIS_MIN_IN)
|
||||
data->xAxis = AXIS_MIN_IN;
|
||||
|
||||
// keep y axis below maxIncline
|
||||
if (data->yAxis > MAX_INCLINE_AXIS_Y)
|
||||
data->yAxis = MAX_INCLINE_AXIS_Y;
|
||||
if (data->yAxis < -MAX_INCLINE_AXIS_Y)
|
||||
data->yAxis = -MAX_INCLINE_AXIS_Y;
|
||||
if (data->yAxis > AXIS_MAX_IN)
|
||||
data->yAxis = AXIS_MAX_IN;
|
||||
if (data->yAxis < AXIS_MIN_IN)
|
||||
data->yAxis = AXIS_MIN_IN;
|
||||
|
||||
//Serial.printf("xaxis: %-3i yaxis: %-3i \n",data->xAxis,data->yAxis);
|
||||
}
|
||||
|
||||
ControllerData controller;
|
||||
|
||||
void loope() {
|
||||
// polling must not occur faster than every 20 ms
|
||||
//delay(14);
|
||||
delay(30);
|
||||
//delay(2000); // todo: change to above
|
||||
void setup() {
|
||||
#ifdef DEBUG
|
||||
Serial.begin(115200);
|
||||
delay(5000);
|
||||
#endif
|
||||
|
||||
gamepad.begin();
|
||||
|
||||
// setup io pins
|
||||
//setupIO();
|
||||
// the controller data line
|
||||
LINE_WRITE_HIGH;
|
||||
|
||||
#ifdef PLOT_CONSOLE_POLLING
|
||||
sendCommand(0x01);
|
||||
while (true)
|
||||
;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < CALIBRATE_PASSES; ++i) {
|
||||
sendCommand(0x01);
|
||||
updateOffsetsAndResolution();
|
||||
if (i != CALIBRATE_PASSES) {
|
||||
delay(14);
|
||||
}
|
||||
}
|
||||
checkBitsToRead();
|
||||
#ifdef DEBUG
|
||||
printf("bitResolution: %i, lastIndex: %i\n", bitResolution, lastIndex);
|
||||
delay(5000);
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// polling must not occur faster than every 20 ms
|
||||
delay(14);
|
||||
|
||||
//Serial.println("sending command to n64");
|
||||
// send command 0x01 to n64 controller
|
||||
sendCommand(0x01);
|
||||
//updateOffsetsAndResolution();
|
||||
|
||||
if (calcReturnedBits() && memcmp(oldReport, returnedBits, sizeof(returnedBits))) {
|
||||
memcpy(oldReport, returnedBits, sizeof(returnedBits));
|
||||
} else {
|
||||
// nothing changed
|
||||
return;
|
||||
}
|
||||
|
||||
// store received data in controller struct
|
||||
populateControllerStruct(&controller);
|
||||
|
||||
// output received data to ique
|
||||
//outputToiQue(&controller);
|
||||
uint8_t c = 0; // for now just do 1 pad
|
||||
gamepad.buttons(c, 0);
|
||||
if (controller.buttonStart) {
|
||||
|
@ -362,11 +419,16 @@ void loope() {
|
|||
}
|
||||
auto hat = calculateDpadDirection(controller.DPadUp, controller.DPadDown, controller.DPadLeft, controller.DPadRight);
|
||||
auto cHat = dpadToAxis(calculateDpadDirection(controller.CUp, controller.CDown, controller.CLeft, controller.CRight));
|
||||
gamepad.setAxis(c, translateAxis(controller.xAxis), translateAxis(controller.yAxis), cHat.x, cHat.y, 0, 0, hat);
|
||||
|
||||
//checkUpdateCombo(&controller);
|
||||
gamepad.setAxis(c, translateAxis(controller.xAxis), -translateAxis(controller.yAxis), cHat.x, cHat.y, 0, 0, hat);
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
for (int i = 0; i < bitsToRead; i++) {
|
||||
Serial.print(buffer[i] ? "1" : "0");
|
||||
}
|
||||
Serial.println("\n----------------");
|
||||
*/
|
||||
|
||||
Serial.print(" buttons: ");
|
||||
Serial.print(controller.buttonA ? "A" : "-");
|
||||
Serial.print(controller.buttonB ? "B" : "-");
|
||||
|
@ -387,69 +449,11 @@ void loope() {
|
|||
Serial.print(" Y: ");
|
||||
Serial.print(controller.yAxis);
|
||||
Serial.print(" YT: ");
|
||||
Serial.print(translateAxis(controller.yAxis));
|
||||
Serial.print(-translateAxis(controller.yAxis));
|
||||
Serial.print(" X: ");
|
||||
Serial.print(controller.xAxis);
|
||||
Serial.print(" XT: ");
|
||||
Serial.print(translateAxis(controller.xAxis));
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
//delay(500);
|
||||
}
|
||||
|
||||
void pinned_loop() {
|
||||
while (true) {
|
||||
loope();
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
#ifdef DEBUG
|
||||
Serial.begin(115200);
|
||||
delay(5000);
|
||||
#endif
|
||||
|
||||
gamepad.begin();
|
||||
|
||||
// setup io pins
|
||||
//setupIO();
|
||||
// the controller data line
|
||||
LINE_WRITE_HIGH;
|
||||
|
||||
#ifdef PLOT_CONSOLE_POLLING
|
||||
sendCommand(0x01);
|
||||
while (true)
|
||||
;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < CALIBRATE_PASSES; ++i) {
|
||||
sendCommand(0x01);
|
||||
updateOffsetsAndResolution();
|
||||
if (i != CALIBRATE_PASSES) {
|
||||
delay(14);
|
||||
}
|
||||
}
|
||||
calcBitsToRead();
|
||||
#ifdef DEBUG
|
||||
printf("bitOffsets: ");
|
||||
for (int i = 0; i < NUM_BITS; i++) {
|
||||
printf("%i:%i ", i, bitOffsets[i]);
|
||||
}
|
||||
printf("\n");
|
||||
printf("bitOffsets: ");
|
||||
for (int i = 0; i < NUM_BITS; i++) {
|
||||
printf("%i, ", bitOffsets[i]);
|
||||
}
|
||||
printf("\n");
|
||||
printf("bitResolution: %i\n", bitResolution);
|
||||
delay(5000);
|
||||
#endif
|
||||
|
||||
//xTaskCreatePinnedToCore(pinned_loop, "gbuttons", 2048, NULL, 1, NULL, 0);
|
||||
//xTaskCreatePinnedToCore(pinned_loop, "gbuttons", 2048, NULL, 1, NULL, 1);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loope();
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@ int bitOffsets[NUM_BITS];
|
|||
int bitResolution = 0;
|
||||
int bitsToRead = DATA_SIZE;
|
||||
|
||||
bool returnedBits[NUM_BITS];
|
||||
|
||||
struct ControllerData {
|
||||
bool buttonA;
|
||||
bool buttonB;
|
||||
|
@ -71,6 +73,7 @@ void updateOffsetsAndResolution() {
|
|||
for (int i = 0; i < NUM_BITS; i++) {
|
||||
bitOffsets[i] += bitResolution;
|
||||
}
|
||||
bitResolution /= 2;
|
||||
|
||||
for (; i < DATA_SIZE; i++) {
|
||||
if (buffer[i] == false) {
|
||||
|
@ -109,6 +112,7 @@ void updateOffsetsAndResolution() {
|
|||
for (int i = 0; i < NUM_BITS; i++) {
|
||||
bitOffsets[i] -= bitResolution;
|
||||
}
|
||||
bitResolution *= 2;
|
||||
}
|
||||
|
||||
void calcBitsToRead() {
|
||||
|
@ -118,6 +122,39 @@ void calcBitsToRead() {
|
|||
}
|
||||
}
|
||||
|
||||
void calcReturnedBits() {
|
||||
// the current bit counter
|
||||
int bitCounter = 0;
|
||||
|
||||
// to hold the number of 1's in this bit
|
||||
int thisResolution = 0;
|
||||
|
||||
// current index
|
||||
int i = 0;
|
||||
for (; i < DATA_SIZE; i++) {
|
||||
if (buffer[i] == false) {
|
||||
// we skip all leading 1's
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// iterate over buffer
|
||||
for (; i < DATA_SIZE - 1 && bitCounter < NUM_BITS; i++) {
|
||||
if (buffer[i] == true) {
|
||||
++thisResolution;
|
||||
// if a falling edge is detected
|
||||
if (buffer[1 + i] == false) {
|
||||
returnedBits[bitCounter] = thisResolution >= bitResolution;
|
||||
|
||||
// reset thisResolution
|
||||
thisResolution = 0;
|
||||
// increment bitCounter
|
||||
++bitCounter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to extract a controller bit from the buffer of returned data */
|
||||
void getBit(bool *bit, int offset, bool *data) {
|
||||
*bit = data[offset];
|
||||
|
@ -129,7 +166,7 @@ void getBit(bool *bit, int offset, bool *data) {
|
|||
* and checking if value if below 'MAX_INCLINE_AXIS_X' or 'MAX_INCLINE_AXIS_Y'.
|
||||
* If values surpass the maximum incline they are set to match those values.
|
||||
*/
|
||||
void populateControllerStruct(ControllerData *data) {
|
||||
void populateControllerStructOLD(ControllerData *data) {
|
||||
// first byte
|
||||
getBit(&(data->buttonA), bitOffsets[0], &buffer[0]);
|
||||
getBit(&(data->buttonB), bitOffsets[1], &buffer[0]);
|
||||
|
@ -226,6 +263,91 @@ void populateControllerStruct(ControllerData *data) {
|
|||
//printf("xaxis: %-3i yaxis: %-3i \n",data->xAxis,data->yAxis);
|
||||
}
|
||||
|
||||
void populateControllerStruct(ControllerData *data) {
|
||||
calcReturnedBits();
|
||||
// first byte
|
||||
data->buttonA = returnedBits[0];
|
||||
data->buttonB = returnedBits[1];
|
||||
data->buttonZ = returnedBits[2];
|
||||
data->buttonStart = returnedBits[3];
|
||||
data->DPadUp = returnedBits[4];
|
||||
data->DPadDown = returnedBits[5];
|
||||
data->DPadLeft = returnedBits[6];
|
||||
data->DPadRight = returnedBits[7];
|
||||
//
|
||||
// second byte, first two bits are unused
|
||||
data->buttonL = returnedBits[10];
|
||||
data->buttonR = returnedBits[11];
|
||||
data->CUp = returnedBits[12];
|
||||
data->CDown = returnedBits[13];
|
||||
data->CRight = returnedBits[14];
|
||||
/*
|
||||
// third byte
|
||||
getBit(&(data->xAxisRaw[0]), bitOffsets[16], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[1]), bitOffsets[17], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[2]), bitOffsets[18], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[3]), bitOffsets[19], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[4]), bitOffsets[20], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[5]), bitOffsets[21], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[6]), bitOffsets[22], &buffer[0]);
|
||||
getBit(&(data->xAxisRaw[7]), bitOffsets[23], &buffer[0]);
|
||||
|
||||
// fourth byte
|
||||
getBit(&(data->yAxisRaw[0]), bitOffsets[24], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[1]), bitOffsets[25], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[2]), bitOffsets[26], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[3]), bitOffsets[27], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[4]), bitOffsets[28], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[5]), bitOffsets[29], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[6]), bitOffsets[30], &buffer[0]);
|
||||
getBit(&(data->yAxisRaw[7]), bitOffsets[31], &buffer[0]);
|
||||
|
||||
// sum up bits to get axis bytes
|
||||
data->xAxis = 0;
|
||||
data->yAxis = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
data->xAxis += (data->xAxisRaw[i] * (0x80 >> (i)));
|
||||
data->yAxis += (data->yAxisRaw[i] * (0x80 >> (i)));
|
||||
}
|
||||
|
||||
// print axis values
|
||||
#ifdef DEBUG
|
||||
printf("yRaw: %i %i %i %i %i %i %i %i xRaw: %i %i %i %i %i %i %i %i yAxis: %03i xAxis: %03i",
|
||||
data->yAxisRaw[0],
|
||||
data->yAxisRaw[1],
|
||||
data->yAxisRaw[2],
|
||||
data->yAxisRaw[3],
|
||||
data->yAxisRaw[4],
|
||||
data->yAxisRaw[5],
|
||||
data->yAxisRaw[6],
|
||||
data->yAxisRaw[7],
|
||||
data->xAxisRaw[0],
|
||||
data->xAxisRaw[1],
|
||||
data->xAxisRaw[2],
|
||||
data->xAxisRaw[3],
|
||||
data->xAxisRaw[4],
|
||||
data->xAxisRaw[5],
|
||||
data->xAxisRaw[6],
|
||||
data->xAxisRaw[7],
|
||||
data->yAxis,
|
||||
data->xAxis);
|
||||
#endif
|
||||
|
||||
// decode xAxis two's complement
|
||||
if (data->xAxis & 0x80) {
|
||||
data->xAxis = -1 * (0xff - data->xAxis);
|
||||
}
|
||||
|
||||
// decode yAxis two's complement
|
||||
if (data->yAxis & 0x80) {
|
||||
data->yAxis = -1 * (0xff - data->yAxis);
|
||||
}
|
||||
|
||||
|
||||
//printf("xaxis: %-3i yaxis: %-3i \n",data->xAxis,data->yAxis);
|
||||
*/
|
||||
}
|
||||
|
||||
void load(const char *s) {
|
||||
const char *t;
|
||||
int i = 0;
|
||||
|
@ -254,7 +376,7 @@ void loadUpdate(const char *s) {
|
|||
}
|
||||
printf("\n");
|
||||
printf("bitResolution: %i\n", bitResolution);
|
||||
printf("bit 0: %i\n", buffer[bitOffsets[0]]);
|
||||
//printf("bit 0: %i\n", buffer[0]]);
|
||||
printf("bit buffer[14]: %i\n", buffer[14]);
|
||||
printf("bit buffer[15]: %i\n", buffer[15]);
|
||||
printf("bit buffer[16]: %i\n", buffer[16]);
|
||||
|
@ -366,13 +488,14 @@ void test_function_realControllerRead(void) {
|
|||
"0011111000000000000000111110000000000000001111100000000000000011110000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
"1111111111111111111111111111111111111111");
|
||||
|
||||
TEST_ASSERT_EQUAL(5, bitResolution);
|
||||
//TEST_ASSERT_EQUAL(5, bitResolution);
|
||||
|
||||
calcBitsToRead();
|
||||
TEST_ASSERT_EQUAL(624, bitsToRead);
|
||||
//TEST_ASSERT_EQUAL(624, bitsToRead);
|
||||
|
||||
load(
|
||||
"0000000000000011110000000000000000111100000000000000001111000000000000000011110000000000000000111100000000000000001111000000000000000011110000000000000000111100000000000000011111000000000000"
|
||||
"0000000000000000000000000000011111111111111011110000000000000000111100000000000000001111000000000000000011110000000000000000111100000000000000001111000000000000000011110000000000000001111100"
|
||||
"0000000000"
|
||||
"0001111100000000000000011111000000000000000111110000000000000001111100000000000000011110000000000000000111100000000000000001111000000111111111111110000001111111111111100000011111111111111000"
|
||||
"0000000000000111100000000000000001111000000111111111111110000001111111111111100000000000000011111000000000000000111110000011111111111111100000000000000011111000000000000000111100000000000000"
|
||||
"001111000000111111111111110000001111111111111100000011");
|
||||
|
|
Loading…
Reference in New Issue