From 78ffc95427073dc9bc43557bb9aa73a652a4b412 Mon Sep 17 00:00:00 2001 From: CrazyRedMachine Date: Thu, 11 Nov 2021 22:06:33 +0100 Subject: [PATCH 1/2] use USBemani codebase --- README.md | 98 +++++++------ src/arduino_psx/arduino_psx.ino | 252 +++++++------------------------- src/arduino_psx/ps2.c | 235 +++++++++++++++++++++++++++++ src/arduino_psx/ps2.h | 46 ++++++ 4 files changed, 391 insertions(+), 240 deletions(-) create mode 100644 src/arduino_psx/ps2.c create mode 100644 src/arduino_psx/ps2.h diff --git a/README.md b/README.md index e261042..3bb6727 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,9 @@ Let's get acquainted with the Playstation cable and color codes. It is always a * **CIPO:** (Controller-In / Peripheral-Out) This is data from the controller to the console. It is held HIGH via a pull-up resistor inside the console. We will use one of the transistors to pull this line to GND. Also known as MISO. * **COPI:** (Controller-Out / Peripheral-In) This is the data from the console to the controller. Also known as MOSI. -* **7.6V:** This typically powers the rumble motors, but we can use it to power the arduino. +* **7.6V:** This typically powers the rumble motors, but we can use it to power the arduino (see `Powering the arduino` in additional notes section). * **GND:** The common ground for the console, also known as 0V. -* **3.3V:** This is power coming from the console. We will not be using this. +* **3.3V:** This is power coming from the console. We can use it to power the arduino (see `Powering the arduino` in additional notes section). * **CS:** (Chip Select) This line goes LOW when the console is requesting data from a controller. This is how the console selects which player's controller to read from. Also known as SS. * **N/C:** This wire is not used (not connected). * **ACK:** This is how the controller tells the console it has finished sending data. It is held HIGH via a pull-up resistor inside the console. The second transistor will pull this line to GND. @@ -47,56 +47,56 @@ The example program follows the wiring below. Please refer to your specific tran ### Pins that can be changed -* ACK +* ACK (see `ps2.c`) ## Basic Use -The example includes D-Pad controls. Connect `A0`, `A1`, `A2`, or `A3`. +### setup() + +- Prepare your input pins by setting them as INPUT_PULLUP + +- Call the `PS2_MapInput(uint16_t *input, uint16_t mask, PS2_INPUT buttons)` function multiple times to setup your button mapping. This will create the link between one bit of your input bitfield (via the mask) and one or several PS2_INPUT buttons + +- (optional) You may also call `PS2_AlwaysInput(PS2_INPUT buttons)` to add constantly pressed inputs to the mapping if needed (some dedicated game controllers work this way) + +- Call `PS2_Init()` + +Valid values for PS2_INPUT buttons are listed in ps2.h : ``` -button_state = 0; -if (digitalRead(A0) == LOW) { - button_state |= PS_LEFT; -} -if (digitalRead(A1) == LOW) { - button_state |= PS_DOWN; -} -if (digitalRead(A2) == LOW) { - button_state |= PS_UP; -} -if (digitalRead(A3) == LOW) { - button_state |= PS_RIGHT; -} +PS2_SELECT +PS2_L3 +PS2_R3 +PS2_START +PS2_UP +PS2_RIGHT +PS2_DOWN +PS2_LEFT +PS2_L2 +PS2_R2 +PS2_L1 +PS2_R1 +PS2_TRIANGLE +PS2_CIRCLE +PS2_CROSS +PS2_SQUARE ``` -To set a button, `BITWISE OR` the correct define with `button_state`. A button is released if it is not pressed during the loop. +### loop() -Valid defines are: +- To set a button, `BITWISE OR` the correct define with `button_state`. A button is released if it is not pressed during the loop -``` -PS_SELECT -PS_L3 -PS_R3 -PS_START -PS_UP -PS_RIGHT -PS_DOWN -PS_LEFT -PS_L2 -PS_R2 -PS_L1 -PS_R1 -PS_TRIANGLE -PS_CIRCLE -PS_CROSS -PS_SQUARE -``` +- Call `PS2_Task()` to poll the console and update inputs + +### Example + +The sketch example includes D-Pad controls and start button, connected to `A0`, `A1`, `A2`, `A3` and `A4`. ### Additional Notes #### Changing the ACK Pin -At the top of the `*.ino` file will be a section to change the ACK pin location. +At the top of the `ps2.c` file will be a section to change the ACK pin location. ``` /* USER CUSTOMIZABLE SETTINGS */ @@ -107,28 +107,40 @@ At the top of the `*.ino` file will be a section to change the ACK pin location. The pin number refers to the `PORT` number, not the standard Arduino number. Refer to the purple tags in the image above. +#### Powering the Arduino + +There are several **mutually exclusive** ways to power the arduino : + +- Use an USB cable with a wall charger (this unfortunately won't work via the PS2 usb port) +- Wire the 7.6 rumble motor line to the arduino `Vin` pin +- Wire the 3.3V line to the arduino `5v` pin (yes, 5v pin, not a typo) + +All of these ways are mutually exclusive. **DO NOT** wire multiple power sources at the same time, this can fry your console. + #### Bypassing the Transistors For safety reasons, I suggest using the transistors as shown above to prevent backfeeding voltage into your console. This has the potential to cause harm. -If you do not use the transistors and directly wire your Arduino to the console, the following line must be changed +If you do not use the transistors and directly wire your Arduino to the console, the following line must be changed at the top of `ps2.c` ``` -#define INVERT_OUTPUT 1 // Set to 1 if CIPO and ACK are open-drain via transistors +#define INVERT_CIPO 1 // Set to 1 if CIPO is open-drain via transistor (recommended) +#define INVERT_ACK 1 // Set to 1 if ACK is open-drain via transistor (recommended) ``` to ``` -#define INVERT_OUTPUT 0 // Set to 1 if CIPO and ACK are open-drain via transistors +#define INVERT_CIPO 0 // Set to 1 if CIPO is open-drain via transistor (recommended) +#define INVERT_ACK 0 // Set to 1 if ACK is open-drain via transistor (recommended) ``` -***THIS IS NOT TESTED AND I DO NOT RECOMMEND IT, I AM NOT LIABLE FOR ANY DAMAGE CAUSED TO YOUR PLAYSTATION.*** +***WHILE THIS HAS BEEN TESTED USING THE 3.3V LINE TO 5V PIN, I DO NOT RECOMMEND IT, I AM NOT LIABLE FOR ANY DAMAGE CAUSED TO YOUR PLAYSTATION.*** ## Credits Wiring and protocol information from [Curious Inventor's page on the Playstation Controller](https://store.curiousinventor.com/guides/PS2) -Code base adapted from [CrazyRedMachine's Ultiamte Pop'n Controller](https://github.com/CrazyRedMachine/UltimatePopnController/tree/PSX), which itself is based on [busslave's PSX_RECEIVER.cpp](https://nfggames.com/forum2/index.php?topic=5001.0). +Code base adapted from [progmem's USBemani v3](https://github.com/progmem/re-usbemani/). Discord User GoroKaneda for getting me to work on and document this, as well as additional testing. \ No newline at end of file diff --git a/src/arduino_psx/arduino_psx.ino b/src/arduino_psx/arduino_psx.ino index a7ea283..ecd79cf 100644 --- a/src/arduino_psx/arduino_psx.ino +++ b/src/arduino_psx/arduino_psx.ino @@ -1,197 +1,55 @@ -/* USER CUSTOMIZABLE SETTINGS */ -#define ACK_PORT PORTB -#define ACK_DDR DDRB -#define ACK_PIN 4 // PB4 (Pin 8 on Micro) - - -/* RECOMMENDED DO NOT CHANGE */ -#define INVERT_OUTPUT 1 // Set to 1 if CIPO and ACK are open-drain via transistors - - - -/* PSX DEFINE */ -#include -#include -#include -#define SPI_PORT PORTB -#define SPI_PINS PINB -#define SPI_DDR DDRB -#define SPI_PINS PINB - -#define ATT_PIN 0 // ~CS -#define CMD_PIN 2 // COPI -#define DATA_PIN 3 // CIPO -#define CLK_PIN 1 // SCK -#define DATA_LEN 5 - -#define PS_SELECT (1 << 0) -#define PS_L3 (1 << 1) -#define PS_R3 (1 << 2) -#define PS_START (1 << 3) -#define PS_UP (1 << 4) -#define PS_RIGHT (1 << 5) -#define PS_DOWN (1 << 6) -#define PS_LEFT (1 << 7) -#define PS_L2 (1 << 8) -#define PS_R2 (1 << 9) -#define PS_L1 (1 << 10) -#define PS_R1 (1 << 11) -#define PS_TRIANGLE (1 << 12) -#define PS_CIRCLE (1 << 13) -#define PS_CROSS (1 << 14) -#define PS_SQUARE (1 << 15) -/* /PSX DEFINE */ - -/* PSX globals */ -#if INVERT_OUTPUT -volatile uint8_t data_buff[DATA_LEN] = {0xBE, 0xA5, 0x00, 0x00, 0x00}; //Reply. -#else -volatile uint8_t data_buff[DATA_LEN] = {0x41, 0x5A, 0xFF, 0xFF, 0xFF}; //Reply. -#endif -volatile uint8_t command_buff[DATA_LEN] = {0x01, 0x42, 0x00, 0x00, 0x00}; - -volatile uint8_t curr_byte = 0; -volatile uint8_t next_byte = 0; - -byte byte4; -byte byte5; - -/* Read bytes in byte4 and byte5 as follows: - +----------+--------+----+----+----+----+----+----+----+----+ - | byte |command | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | - +==========+========+====+====+====+====+====+====+====+====+ - | 1st byte | 0x01 | ----- | - +----------+--------+---------------------------------------+ - | 2nd byte | 0x42 | 0x41 | 'A' - +----------+--------+---------------------------------------+ - | 3rd byte | 0x00 | 0x5a | 'Z' - +----------+--------+----+----+----+----+----+----+----+----+ - | 4th byte | 0x00 | L | DW | R | UP | ST | 1 | 1 |SEL | - +----------+--------+----+----+----+----+----+----+----+----+ - | 5th byte | 0x00 | [] | X | O | <| | R1 | L1 | R2 | L2 | - +----------+--------+----+----+----+----+----+----+----+----+ -*/ -/* NOTE: a bit set to 1 is unpressed, a bit set to 0 is pressed */ -void convertInputToPSX(uint16_t state) { - - byte4 = ~(state & 0xFF); - byte5 = ~((state >> 8) & 0xFF); - -#if INVERT_OUTPUT - data_buff[2] = ~byte4; - data_buff[3] = ~byte5; -#else - data_buff[2] = byte4; - data_buff[3] = byte5; -#endif -} - -ISR(SPI_STC_vect) { - uint8_t inbyte = SPDR; - - if (inbyte == command_buff[curr_byte]) { -#if INVERT_OUTPUT == 0 - SPI_DDR |= (1 << DATA_PIN); // output -#endif - SPDR = data_buff[curr_byte]; - curr_byte++; - if (curr_byte < DATA_LEN) { - _delay_us(8); // Necessary delay for PS1 (not needed for PS2) - // Set ACK low -#if INVERT_OUTPUT - ACK_PORT |= (1 << ACK_PIN); -#else - ACK_DDR |= (1 << ACK_PIN); // output - ACK_PORT &= ~(1 << ACK_PIN); -#endif - _delay_us(1); - // Set ACK high -#if INVERT_OUTPUT - ACK_PORT &= ~(1 << ACK_PIN); // Release ACK -#else - ACK_DDR &= ~(1 << ACK_PIN); // input - ACK_PORT &= ~(1 << ACK_PIN); // ensure pullup is off -#endif - - } else { - SPDR = 0xFF; - curr_byte = 0; - } - } else { - SPDR = 0xFF; - curr_byte = 0; - } -} -/* /PSX globals */ - -uint16_t button_state = 0; - -void setup() { - - /* PSX setup */ -#if INVERT_OUTPUT - ACK_DDR |= (1 << ACK_PIN); // output - ACK_PORT &= ~(1 << ACK_PIN); // set LOW (open drain -- pull-up on console) - - SPI_DDR |= (1 << DATA_PIN); // output - SPI_PORT &= ~(1 << DATA_PIN); //set LOW (open drain -- pull-up on console) -#else - ACK_DDR &= ~(1 << ACK_PIN); // input - ACK_PORT &= ~(1 << ACK_PIN); // ensure pullup is off - - SPI_DDR &= ~(1 << DATA_PIN); // input - SPI_PORT &= ~(1 << DATA_PIN); // ensure pullup is off -#endif - - //SPI setup - SPCR |= (1 << SPR1); // Fosc/64. @16MHz==250KHz. - SPCR |= (1 << CPHA); // Setup @ leading edge, sample @ falling edge. - SPCR |= (1 << CPOL); // Leading edge is falling edge, trailing edge is rising edge. - SPCR &= ~(1 << MSTR); // MSTR bit is zero, SPI is slave. - SPCR |= (1 << DORD); // Byte is transmitted LSB first, MSB last. - SPCR |= (1 << SPE); // Enable SPI. - SPCR |= (1 << SPIE); // Enable Serial Transfer Complete (STC) interrupt. - SPDR = 0xFF; - - sei(); // Enable global interrupts - /* /PSX setup */ - -/* --- --- --- --- --- --- */ -/* USER CODE STARTS HERE */ -/* --- --- --- --- --- --- */ - - pinMode(A0, INPUT_PULLUP); - pinMode(A1, INPUT_PULLUP); - pinMode(A2, INPUT_PULLUP); - pinMode(A3, INPUT_PULLUP); -} - -void loop() { - - button_state = 0; - if (digitalRead(A0) == LOW) { - button_state |= PS_LEFT; - } - if (digitalRead(A1) == LOW) { - button_state |= PS_DOWN; - } - if (digitalRead(A2) == LOW) { - button_state |= PS_UP; - } - if (digitalRead(A3) == LOW) { - button_state |= PS_RIGHT; - } - -/* --- --- --- --- --- --- */ -/* USER CODE ENDS HERE */ -/* --- --- --- --- --- --- */ - - convertInputToPSX(button_state); - -#if INVERT_OUTPUT == 0 - if ((SPI_PORT & (1 << ATT_PIN) > 0)) { - SPI_DDR &= ~(1 << DATA_PIN); // input - SPI_PORT &= ~(1 << DATA_PIN); // ensure pullup is off - } -#endif -} +#include "ps2.h" + +/* internal button state define */ +#define BUTTON_1 (1<<0) +#define BUTTON_2 (1<<1) +#define BUTTON_3 (1<<2) +#define BUTTON_4 (1<<3) +#define BUTTON_5 (1<<4) + +uint16_t button_state = 0; + +void setup() { + /* Pins setup */ + pinMode(A0, INPUT_PULLUP); + pinMode(A1, INPUT_PULLUP); + pinMode(A2, INPUT_PULLUP); + pinMode(A3, INPUT_PULLUP); + pinMode(A4, INPUT_PULLUP); + + /* PS2 Input Mapping */ + // map bits from internal button state bitfield to the corresponding PS buttons + PS2_MapInput(&button_state, BUTTON_1, PS2_UP); + PS2_MapInput(&button_state, BUTTON_2, PS2_DOWN); + PS2_MapInput(&button_state, BUTTON_3, PS2_LEFT); + PS2_MapInput(&button_state, BUTTON_4, PS2_RIGHT); + PS2_MapInput(&button_state, BUTTON_5, PS2_START); + // if you need your controller to keep some buttons always pressed (e.g. pop'n controller) + //PS2_AlwaysInput(PS2_LEFT|PS2_DOWN|PS2_RIGHT); + + /* PS2 Init */ + PS2_Init(); +} + +void loop() { + + button_state = 0; + if (digitalRead(A0) == LOW) { + button_state |= BUTTON_1; + } + if (digitalRead(A1) == LOW) { + button_state |= BUTTON_2; + } + if (digitalRead(A2) == LOW) { + button_state |= BUTTON_3; + } + if (digitalRead(A3) == LOW) { + button_state |= BUTTON_4; + } + if (digitalRead(A4) == LOW) { + button_state |= BUTTON_5; + } + + PS2_Task(); + +} diff --git a/src/arduino_psx/ps2.c b/src/arduino_psx/ps2.c new file mode 100644 index 0000000..8b7f08f --- /dev/null +++ b/src/arduino_psx/ps2.c @@ -0,0 +1,235 @@ +#include "ps2.h" + +/* USER CUSTOMIZABLE SETTINGS */ +#define ACK_PORT PORTB +#define ACK_DDR DDRB +#define ACK_PIN 4 // PB4 (Pin 8 on Micro) + +/* RECOMMENDED DO NOT CHANGE */ +#define INVERT_CIPO 1 // Set to 1 if CIPO is open-drain via transistor (recommended) +#define INVERT_ACK 1 // Set to 1 if ACK is open-drain via transistor (recommended) + +/* END OF USER CUSTOMIZABLE SETTINGS */ + +// Stores a constructed packet for the PS2. +uint16_t Data = 0; +// List of available PS2 inputs. +PS2_InputList_t *PS2Input = NULL; +// Current PS2 state. +void (*PS2Handler)(uint8_t) = NULL; + + + +void PS2_Acknowledge(void) { + // Burn a few cycles before acknowledging + asm volatile( + "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n" + ); +#if INVERT_ACK == 0 + ACK_DDR |= (1<input || (*map->input & map->mask)) + new_data |= map->buttons; + + map = map->parent; + } + + Data = ~new_data; +} + +void PS2_MapInput(uint16_t *input, uint16_t mask, PS2_INPUT buttons) { + PS2_InputList_t *child = calloc(1, sizeof(PS2_InputList_t)); + + child->input = input, + child->mask = mask, + child->buttons = buttons, + child->parent = PS2Input; + + PS2Input = child; +} + +void PS2_AlwaysInput(PS2_INPUT buttons) { + PS2_InputList_t *child = calloc(1, sizeof(PS2_InputList_t)); + + child->input = NULL, + child->mask = 0, + child->buttons = buttons, + child->parent = PS2Input; + + PS2Input = child; +} + +// When a transfer is complete, determine what to do next +ISR(SPI_STC_vect) { + uint8_t input = SPDR; + if (input == 0x01 && (!memory_card_timeout)) PS2Handler = PS2_Listen; + PS2Handler(SPDR); +} diff --git a/src/arduino_psx/ps2.h b/src/arduino_psx/ps2.h new file mode 100644 index 0000000..b3bad14 --- /dev/null +++ b/src/arduino_psx/ps2.h @@ -0,0 +1,46 @@ +#include +#include +#include + +typedef enum { + PS2_NC = 0, + PS2_SELECT = (1 << 0), + PS2_L3 = (1 << 1), + PS2_R3 = (1 << 2), + PS2_START = (1 << 3), + PS2_UP = (1 << 4), + PS2_RIGHT = (1 << 5), + PS2_DOWN = (1 << 6), + PS2_LEFT = (1 << 7), + PS2_L2 = (1 << 8), + PS2_R2 = (1 << 9), + PS2_L1 = (1 << 10), + PS2_R1 = (1 << 11), + PS2_TRIANGLE = (1 << 12), + PS2_CIRCLE = (1 << 13), + PS2_CROSS = (1 << 14), + PS2_SQUARE = (1 << 15), +} PS2_INPUT; + +typedef struct PS2_InputList_t PS2_InputList_t; + +struct PS2_InputList_t { + uint16_t *input; // Input source; NULL is always true + uint16_t mask; // Mask to check; (*input & mask) + PS2_INPUT buttons; // OR the following if true + PS2_InputList_t *parent; +}; + +#ifdef __cplusplus +extern "C"{ +#endif + +void PS2_Init(void); +void PS2_Task(void); + +void PS2_MapInput(uint16_t *input, uint16_t mask, PS2_INPUT buttons); +void PS2_AlwaysInput(PS2_INPUT buttons); + +#ifdef __cplusplus +} +#endif -- 2.54.0 From de852bcc674f69bc6640378d755f2cc1993b617e Mon Sep 17 00:00:00 2001 From: CrazyRedMachine Date: Mon, 22 Nov 2021 20:05:55 +0100 Subject: [PATCH 2/2] USBemani codebase update --- src/arduino_psx/arduino_psx.ino | 68 ++++++++++++--- src/arduino_psx/ps2.c | 149 ++++++++++---------------------- src/arduino_psx/ps2.h | 8 +- 3 files changed, 109 insertions(+), 116 deletions(-) diff --git a/src/arduino_psx/arduino_psx.ino b/src/arduino_psx/arduino_psx.ino index ecd79cf..7c84bc5 100644 --- a/src/arduino_psx/arduino_psx.ino +++ b/src/arduino_psx/arduino_psx.ino @@ -6,16 +6,27 @@ #define BUTTON_3 (1<<2) #define BUTTON_4 (1<<3) #define BUTTON_5 (1<<4) +#define BUTTON_6 (1<<5) +#define BUTTON_7 (1<<6) +#define BUTTON_8 (1<<7) +#define BUTTON_9 (1<<8) +#define BUTTON_10 (1<<9) uint16_t button_state = 0; void setup() { /* Pins setup */ - pinMode(A0, INPUT_PULLUP); - pinMode(A1, INPUT_PULLUP); - pinMode(A2, INPUT_PULLUP); - pinMode(A3, INPUT_PULLUP); - pinMode(A4, INPUT_PULLUP); + pinMode(0, INPUT_PULLUP); + pinMode(1, INPUT_PULLUP); + pinMode(2, INPUT_PULLUP); + pinMode(3, INPUT_PULLUP); + pinMode(4, INPUT_PULLUP); + pinMode(5, INPUT_PULLUP); + pinMode(6, INPUT_PULLUP); + pinMode(7, INPUT_PULLUP); + pinMode(8, INPUT_PULLUP); + pinMode(9, INPUT_PULLUP); + pinMode(10, INPUT_PULLUP); /* PS2 Input Mapping */ // map bits from internal button state bitfield to the corresponding PS buttons @@ -23,31 +34,64 @@ void setup() { PS2_MapInput(&button_state, BUTTON_2, PS2_DOWN); PS2_MapInput(&button_state, BUTTON_3, PS2_LEFT); PS2_MapInput(&button_state, BUTTON_4, PS2_RIGHT); - PS2_MapInput(&button_state, BUTTON_5, PS2_START); + PS2_MapInput(&button_state, BUTTON_5, PS2_TRIANGLE); + PS2_MapInput(&button_state, BUTTON_6, PS2_CROSS); + PS2_MapInput(&button_state, BUTTON_7, PS2_SQUARE); + PS2_MapInput(&button_state, BUTTON_8, PS2_CIRCLE); + PS2_MapInput(&button_state, BUTTON_9, PS2_START); + PS2_MapInput(&button_state, BUTTON_10,PS2_SELECT); // if you need your controller to keep some buttons always pressed (e.g. pop'n controller) //PS2_AlwaysInput(PS2_LEFT|PS2_DOWN|PS2_RIGHT); /* PS2 Init */ - PS2_Init(); + // Indicate how MISO will be used for the PS2. + // * PS2_TRANSISTOR is the most reliable method, requiring an N-Channel MOSFET or transistor. + // * Connect the AVR MISO pin to the base/gate. + // * Connect the PS2 MISO pin to the collector/drain. + // * Connect the emitter/source to ground. + // * The BS170 N-Channel MOSFET works well with no gate resistor. + // * PS2_DIRECT can be used if running at 3.3V. + // * This will provide varying levels of success based on a number of factors. + // * Cable quality and the presence of a ferrite core are factors that come to play. + // * A generic PS1 extension with no ferrites can work better than Konami's cable! + // * If PS2_DIRECT doesn't work for you, you must use PS2_TRANSISTOR. + // + // Additionally, indicate which pin you want to use for PS2 "Acknowledge" line in the header of ps2.c + PS2_Init(PS2_DIRECT); } void loop() { button_state = 0; - if (digitalRead(A0) == LOW) { + if (digitalRead(0) == LOW) { button_state |= BUTTON_1; } - if (digitalRead(A1) == LOW) { + if (digitalRead(1) == LOW) { button_state |= BUTTON_2; } - if (digitalRead(A2) == LOW) { + if (digitalRead(2) == LOW) { button_state |= BUTTON_3; } - if (digitalRead(A3) == LOW) { + if (digitalRead(3) == LOW) { button_state |= BUTTON_4; } - if (digitalRead(A4) == LOW) { + if (digitalRead(4) == LOW) { button_state |= BUTTON_5; + } + if (digitalRead(5) == LOW) { + button_state |= BUTTON_6; + } + if (digitalRead(6) == LOW) { + button_state |= BUTTON_7; + } + if (digitalRead(7) == LOW) { + button_state |= BUTTON_8; + } + if (digitalRead(8) == LOW) { + button_state |= BUTTON_9; + } + if (digitalRead(9) == LOW) { + button_state |= BUTTON_10; } PS2_Task(); diff --git a/src/arduino_psx/ps2.c b/src/arduino_psx/ps2.c index 8b7f08f..a04d70c 100644 --- a/src/arduino_psx/ps2.c +++ b/src/arduino_psx/ps2.c @@ -4,32 +4,37 @@ #define ACK_PORT PORTB #define ACK_DDR DDRB #define ACK_PIN 4 // PB4 (Pin 8 on Micro) - -/* RECOMMENDED DO NOT CHANGE */ -#define INVERT_CIPO 1 // Set to 1 if CIPO is open-drain via transistor (recommended) -#define INVERT_ACK 1 // Set to 1 if ACK is open-drain via transistor (recommended) - /* END OF USER CUSTOMIZABLE SETTINGS */ +// Port and Pin mask to setup +uint8_t PinMask = (1< #include #include +typedef enum { + PS2_DIRECT = 0x00, + PS2_TRANSISTOR = 0xFF, +} PS2_INVERT; + typedef enum { PS2_NC = 0, PS2_SELECT = (1 << 0), @@ -35,7 +41,7 @@ struct PS2_InputList_t { extern "C"{ #endif -void PS2_Init(void); +void PS2_Init(PS2_INVERT invert); void PS2_Task(void); void PS2_MapInput(uint16_t *input, uint16_t mask, PS2_INPUT buttons); -- 2.54.0