#include "ps2.h" #if defined(ARDUINO_ARCH_AVR) /* USER CUSTOMIZABLE SETTINGS */ #define ACK_PORT PORTD #define ACK_DDR DDRD #define ACK_PIN 5 // PD5 (TXLED) /* RECOMMENDED DO NOT CHANGE */ #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) /* 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); } #endif