diff --git a/popnController/POPNHID.cpp b/popnController/POPNHID.cpp index 06ac5bb..bc2a3db 100644 --- a/popnController/POPNHID.cpp +++ b/popnController/POPNHID.cpp @@ -1,363 +1,411 @@ -/* Arduino-HID-Lighting-Library - * - * This Arduino-HID-Lighting-Library is derived from Arduino-HID-Lighting, whose copyriht owner is mon. - * More information about Arduino-HID-Lighting you can find under: - * - * mon's Arduino-HID-Lighting - * https://github.com/mon/Arduino-HID-Lighting - * - * 2018 (C) Arduino-HID-Lighting-Library, Knuckleslee -*/ -#include "POPNHID.h" - -byte extern LightPins[]; - -/* HID DESCRIPTOR */ -static const byte PROGMEM _hidReportPOPN[] = { - 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ - 0x09, 0x05, /* USAGE (Game Pad) */ - 0xa1, 0x01, /* COLLECTION (Application) */ - - /*Buttons */ - 0x85, 0x04, /* REPORT_ID 4 */ - 0x05, 0x09, /* USAGE_PAGE (Button) */ - 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */ - 0x29, 0x0c, /* USAGE_MAXIMUM (Button 12)*/ - 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ - 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ -#if defined(ARDUINO_ARCH_SAM) - 0x95, 0x0c, /* REPORT_COUNT (12) */ -#else - 0x95, 0x0b, /* REPORT_COUNT (11) */ -#endif - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x81, 0x02, /* INPUT (Data,Var,Abs) */ - /* Reserved bits */ - 0x95, 0x01, /* REPORT_COUNT (1) */ -#if defined(ARDUINO_ARCH_SAM) - 0x75, 0x04, /* REPORT_SIZE (4) */ -#else - 0x75, 0x05, /* REPORT_SIZE (5) */ -#endif - 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ - - /*Lights */ - 0x85, 0x05, /* REPORT_ID 5*/ - 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ - 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ - /*Led 1 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x01, /* USAGE (Instance 1) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 2 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x02, /* USAGE (Instance 2) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 3 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x03, /* USAGE (Instance 3) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 4 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x04, /* USAGE (Instance 4) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 5 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x05, /* USAGE (Instance 5) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 6 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x06, /* USAGE (Instance 6) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 7 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x07, /* USAGE (Instance 7) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 8 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x08, /* USAGE (Instance 8) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 9 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x09, /* USAGE (Instance 9) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ -#if defined(ARDUINO_ARCH_SAM) - /*Led 10 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x0a, /* USAGE (Instance 10) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 11 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x0b, /* USAGE (Instance 11) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 12 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x0c, /* USAGE (Instance 12) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 13 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x0d, /* USAGE (Instance 13) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 14 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x0e, /* USAGE (Instance 14) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 15 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x0f, /* USAGE (Instance 15) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 16 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x10, /* USAGE (Instance 16) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 17 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x11, /* USAGE (Instance 17) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /*Led 18 */ - 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ - 0x09, 0x12, /* USAGE (Instance 18) */ - 0xa1, 0x02, /* COLLECTION (Logical) */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - 0xc0, /* END_COLLECTION */ - /* Reserved 14 bits */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x75, 0x0E, /* REPORT_SIZE (14) */ - 0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */ -#else - /* Reserved 23 bits */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x75, 0x17, /* REPORT_SIZE (23) */ - 0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */ -#endif - /*Footer */ - 0xc0 /* END_COLLECTION */ -}; - -/* PluggableUSBModule IMPLEMENTATION */ - - POPNHID_::POPNHID_(void) : PluggableUSBModule(1, 1, epType) { - epType[0] = EP_TYPE_INTERRUPT_IN; - PluggableUSB().plug(this); - } - - int POPNHID_::getInterface(byte* interfaceCount) { - *interfaceCount += 1; // uses 1 - HIDDescriptor hidInterface = { - D_INTERFACE(pluggedInterface, 1, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_NONE, HID_PROTOCOL_NONE), - D_HIDREPORT(sizeof(_hidReportPOPN)), - D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01) // this last parameter is the bInterval (requested polling rate) - }; - return USB_SendControl(0, &hidInterface, sizeof(hidInterface)); - } - - int POPNHID_::getDescriptor(USBSetup& setup) - { - // Check if this is a HID Class Descriptor request - if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0; } - if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { return 0; } - - // In a HID Class Descriptor wIndex contains the interface number - if (setup.wIndex != pluggedInterface) { return 0; } - - return USB_SendControl(TRANSFER_PGM, _hidReportPOPN, sizeof(_hidReportPOPN)); - } - - bool POPNHID_::setup(USBSetup& setup) - { - if (pluggedInterface != setup.wIndex) { - return false; - } - - byte request = setup.bRequest; - byte requestType = setup.bmRequestType; - - if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE) - { - return true; - } - - if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE) { - if (request == HID_SET_REPORT) { - if(setup.wValueH == HID_REPORT_TYPE_OUTPUT && setup.wLength == 5){ - lastHidUpdate = millis(); - USB_RecvControl(led_data, 5); - return true; - } - } - } - - return false; - } - - uint8_t POPNHID_::getShortName(char *name) - { - name[0] = 'P'; - name[1] = 'O'; - name[2] = 'P'; - name[3] = 'N'; - return 4; - } - -/* CUSTOM POPN FUNCTIONS */ - - uint8_t POPNHID_::getLightMode(){ - return lightMode; - } - - unsigned long POPNHID_::getLastHidUpdate(){ - return lastHidUpdate; - } - - void POPNHID_::setLightMode(uint8_t mode){ - if ((mode > 4) || (mode < 0)) { - lightMode = 2; - return; - } - lightMode = mode; - } - - void POPNHID_::updateLightMode(){ - uint32_t* bitfield = (uint32_t*)&(led_data[1]); - if (*bitfield>>28&1){ - uint8_t mode = (*bitfield>>24) & 0x0F; - setLightMode(mode); - *bitfield &= ~((uint32_t)0xFF<<24); - } - } - - void POPNHID_::updateLeds(uint32_t buttonsState, bool invert){ - uint32_t* bitfield = (uint32_t*)&(led_data[1]); - uint32_t leds = (*bitfield|buttonsState); - if (invert) - leds = ~leds; - for(int i = 0; i < 9; i++) { - if (leds>>i&1) - digitalWrite(LightPins[i],HIGH); - else - digitalWrite(LightPins[i],LOW); - } -#if defined(ARDUINO_ARCH_SAM) - for(int i = 9; i < 18; i++) { - if (leds>>i&1) - digitalWrite(LightPins[i],HIGH); - else - digitalWrite(LightPins[i],LOW); - } -#endif - - } - - int POPNHID_::sendState(uint32_t buttonsState){ - uint8_t data[3]; - data[0] = (uint8_t) 4; //report id - data[1] = (uint8_t) (buttonsState & 0xFF); - data[2] = (uint8_t) (buttonsState >> 8) & 0xFF; - return USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, 3); - } +/* Arduino-HID-Lighting-Library + + This Arduino-HID-Lighting-Library is derived from Arduino-HID-Lighting, whose copyriht owner is mon. + More information about Arduino-HID-Lighting you can find under: + + mon's Arduino-HID-Lighting + https://github.com/mon/Arduino-HID-Lighting + + 2018 (C) Arduino-HID-Lighting-Library, Knuckleslee +*/ +#include "POPNHID.h" +#include + +/* HID DESCRIPTOR */ +static const byte PROGMEM _hidReportPOPN[] = { + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x05, /* USAGE (Game Pad) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + + /*Buttons */ + 0x85, 0x04, /* REPORT_ID 4 */ + 0x05, 0x09, /* USAGE_PAGE (Button) */ + 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */ + 0x29, 0x0c, /* USAGE_MAXIMUM (Button 12)*/ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x95, 0x0c, /* REPORT_COUNT (12) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + /* Reserved bits */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x04, /* REPORT_SIZE (4) */ + 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ + + /*Lights */ + 0x85, 0x05, /* REPORT_ID 5*/ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + /*Led 1 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x01, /* USAGE (Instance 1) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 2 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x02, /* USAGE (Instance 2) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 3 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x03, /* USAGE (Instance 3) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 4 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x04, /* USAGE (Instance 4) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 5 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x05, /* USAGE (Instance 5) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 6 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x06, /* USAGE (Instance 6) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 7 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x07, /* USAGE (Instance 7) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 8 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x08, /* USAGE (Instance 8) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 9 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x09, /* USAGE (Instance 9) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 10 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x0a, /* USAGE (Instance 10) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 11 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x0b, /* USAGE (Instance 11) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 12 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x0c, /* USAGE (Instance 12) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 13 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x0d, /* USAGE (Instance 13) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 14 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x0e, /* USAGE (Instance 14) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 15 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x0f, /* USAGE (Instance 15) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 16 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x10, /* USAGE (Instance 16) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 17 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x11, /* USAGE (Instance 17) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /*Led 18 */ + 0x05, 0x0a, /* USAGE_PAGE (Ordinals) */ + 0x09, 0x12, /* USAGE (Instance 18) */ + 0xa1, 0x02, /* COLLECTION (Logical) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x09, 0x4b, /* USAGE (Generic Indicator 1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ + /* Reserved 14 bits */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x0E, /* REPORT_SIZE (14) */ + 0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */ + /*Footer */ + 0xc0 /* END_COLLECTION */ +}; + +/* PluggableUSBModule IMPLEMENTATION */ + +POPNHID_::POPNHID_(void) : PluggableUSBModule(1, 1, epType) { + epType[0] = EP_TYPE_INTERRUPT_IN; + PluggableUSB().plug(this); +} + +int POPNHID_::getInterface(byte* interfaceCount) { + *interfaceCount += 1; // uses 1 + HIDDescriptor hidInterface = { + D_INTERFACE(pluggedInterface, 1, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_NONE, HID_PROTOCOL_NONE), + D_HIDREPORT(sizeof(_hidReportPOPN)), + D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01) // this last parameter is the bInterval (requested polling rate) + }; + return USB_SendControl(0, &hidInterface, sizeof(hidInterface)); +} + +int POPNHID_::getDescriptor(USBSetup& setup) +{ + // Check if this is a HID Class Descriptor request + if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { + return 0; + } + if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { + return 0; + } + + // In a HID Class Descriptor wIndex contains the interface number + if (setup.wIndex != pluggedInterface) { + return 0; + } + + return USB_SendControl(TRANSFER_PGM, _hidReportPOPN, sizeof(_hidReportPOPN)); +} + +bool POPNHID_::setup(USBSetup& setup) +{ + if (pluggedInterface != setup.wIndex) { + return false; + } + + byte request = setup.bRequest; + byte requestType = setup.bmRequestType; + + if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE) + { + return true; + } + + if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE) { + if (request == HID_SET_REPORT) { + if (setup.wValueH == HID_REPORT_TYPE_OUTPUT && setup.wLength == 5) { + lastHidUpdate = millis(); + USB_RecvControl(led_data, 5); + return true; + } + } + } + + return false; +} + +uint8_t POPNHID_::getShortName(char *name) +{ + name[0] = 'P'; + name[1] = 'O'; + name[2] = 'P'; + name[3] = 'N'; + return 4; +} + +/* CUSTOM POPN FUNCTIONS */ + +uint8_t POPNHID_::getLightMode() { + return lightMode; +} + +unsigned long POPNHID_::getLastHidUpdate() { + return lastHidUpdate; +} + +void POPNHID_::setLightMode(uint8_t mode) { + if ((mode > 4) || (mode < 0)) { + lightMode = 2; + return; + } + lightMode = mode; +} + +void POPNHID_::updateLightMode() { + uint32_t* bitfield = (uint32_t*) & (led_data[1]); + if (*bitfield >> 28 & 1) { + uint8_t mode = (*bitfield >> 24) & 0x0F; + setLightMode(mode); + *bitfield &= ~((uint32_t)0xFF << 24); + } +} + +#define BUT_LED_PIN A0 +#define BUT_NUM_LEDS 9 +#define LEFT_LED_PIN 8 +#define LEFT_NUM_LEDS 9 +#define RIGHT_LED_PIN 9 +#define RIGHT_NUM_LEDS 9 +CRGB extern but_leds[]; +CRGB extern left_leds[]; +CRGB extern right_leds[]; +CRGB extern but_led_colors[]; +byte extern lightOrder[]; +byte extern NeonPins[]; +#define PILLAR_BRIGHTNESS 64 +#define BUTTON_BRIGHTNESS 220 +uint16_t popnhid_convert_order(uint16_t lightDesc) { + uint16_t res = 0; + for (int i = 0; i < BUT_NUM_LEDS; i++) { + if ((lightDesc >> i) & 1) { + res |= 1 << (lightOrder[i]); + } + } + return res; +} +/* Light up button lights according to bitfield */ +void popnhid_but_lights(uint16_t lightDesc) { + //conversion de lightDesc + lightDesc = popnhid_convert_order(lightDesc); + + //allumage + for (int i = 0; i < BUT_NUM_LEDS; i++) { + if ((lightDesc >> i) & 1) { + but_leds[i] = but_led_colors[i]; + } else { + but_leds[i] = 0; + } + } + FastLED.show(); +} + +/* Light up pillars and top neons according to bitfield */ +void popnhid_neon_lights(uint16_t lightDesc) { + //Top-Lamp + for (int i = 0; i < 5; i++) { + if ((lightDesc >> i) & 1) { + digitalWrite(NeonPins[i], HIGH); + } else { + digitalWrite(NeonPins[i], LOW); + } + } + + //LEFT + CRGB left_color = 0; + if ((lightDesc >> 5) & 1) left_color.b += PILLAR_BRIGHTNESS; + if ((lightDesc >> 6) & 1) left_color.r += PILLAR_BRIGHTNESS; + for (int i = 1; i < 8; i++) { + left_leds[i] = left_color; + } + //RIGHT + CRGB right_color = 0; + if ((lightDesc >> 7) & 1) right_color.b += PILLAR_BRIGHTNESS; + if ((lightDesc >> 8) & 1) right_color.r += PILLAR_BRIGHTNESS; + for (int i = 1; i < 8; i++) { + right_leds[i] = right_color; + } + + + FastLED.show(); +} + +void POPNHID_::updateLeds(uint32_t buttonsState, bool invert) { + uint32_t* bitfield = (uint32_t*) & (led_data[1]); + uint32_t leds = (*bitfield | buttonsState); + if (invert) + leds = ~leds; + + //ici on allume les boutons + popnhid_but_lights((uint16_t) leds); + popnhid_neon_lights((uint16_t) (leds >> 16)); +} + +int POPNHID_::sendState(uint32_t buttonsState) { + uint8_t data[3]; + data[0] = (uint8_t) 4; //report id + data[1] = (uint8_t) (buttonsState & 0xFF); + data[2] = (uint8_t) (buttonsState >> 8) & 0xFF; + return USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, 3); +} diff --git a/popnController/POPNHID.h b/popnController/POPNHID.h index 29a2443..a2a663c 100644 --- a/popnController/POPNHID.h +++ b/popnController/POPNHID.h @@ -1,79 +1,58 @@ -#include "HID.h" - -#if defined(ARDUINO_ARCH_AVR) - -#define EPTYPE_DESCRIPTOR_SIZE uint8_t - -#elif defined(ARDUINO_ARCH_SAM) - -#define EPTYPE_DESCRIPTOR_SIZE uint32_t -#define USB_EP_SIZE 64 -#define TRANSFER_PGM 0x80 -#define USB_SendControl USBD_SendControl -#define USB_RecvControl USBD_RecvControl -#define USB_Recv USBD_Recv -#define USB_Send USBD_Send -#define USB_Flush USBD_Flush -#define HID_REPORT_TYPE_OUTPUT 2 -#define HID_REPORT_TYPE_INPUT 1 - -#else - -#error "Unsupported architecture" - -#endif - -class POPNHID_ : public PluggableUSBModule { - - public: - POPNHID_(void); - - /** - * Updates the led status based on led_data (HID report received) and button states - * param[in] buttonState bitfield with currently pressed buttons (used to force additional lights for mixed mode) - * param[in] invert set to true to invert on/off status (used for invert lightmode) - */ - void updateLeds(uint32_t buttonsState, bool invert); - - /** - * Sends the gamepad button states to the PC as an HID report - * param[in] buttonsState bitfield with currently pressed buttons - * return USB_Send() return value - */ - int sendState(uint32_t buttonsState); - - /** - * Changes the lightMode if a received HID report asks for it - */ - void updateLightMode(); - - /** - * getter and setter for lightMode protected field. - */ - uint8_t getLightMode(); - void setLightMode(uint8_t mode); - - /** - * getter for lastHidUpdate protected field. - */ - unsigned long getLastHidUpdate(); - - protected: - /* current lightMode (0 = reactive, 1 = HID only, 2 = mixed (HID+reactive auto-switch), 3 = combined (HID+button presses), 4 = combined invert) */ - uint8_t lightMode = 2; - /* timestamp of last received HID report for lightMode 3 */ - unsigned long lastHidUpdate = 0; - /* byte array to receive HID reports from the PC */ - byte led_data[5]; - - /* Implementation of the PUSBListNode */ - EPTYPE_DESCRIPTOR_SIZE epType[1]; - uint8_t protocol; - uint8_t idle; - int getInterface(uint8_t* interfaceCount); - int getDescriptor(USBSetup& setup); - bool setup(USBSetup& setup); - uint8_t getShortName(char *name); -}; - -extern POPNHID_ POPNHID; +#include + +#define EPTYPE_DESCRIPTOR_SIZE uint8_t + +class POPNHID_ : public PluggableUSBModule { + + public: + POPNHID_(void); + + /** + Updates the led status based on led_data (HID report received) and button states + param[in] buttonState bitfield with currently pressed buttons (used to force additional lights for mixed mode) + param[in] invert set to true to invert on/off status (used for invert lightmode) + */ + void updateLeds(uint32_t buttonsState, bool invert); + + /** + Sends the gamepad button states to the PC as an HID report + param[in] buttonsState bitfield with currently pressed buttons + return USB_Send() return value + */ + int sendState(uint32_t buttonsState); + + /** + Changes the lightMode if a received HID report asks for it + */ + void updateLightMode(); + + /** + getter and setter for lightMode protected field. + */ + uint8_t getLightMode(); + void setLightMode(uint8_t mode); + + /** + getter for lastHidUpdate protected field. + */ + unsigned long getLastHidUpdate(); + + protected: + /* current lightMode (0 = reactive, 1 = HID only, 2 = mixed (HID+reactive auto-switch), 3 = combined (HID+button presses), 4 = combined invert) */ + uint8_t lightMode = 2; + /* timestamp of last received HID report for lightMode 3 */ + unsigned long lastHidUpdate = 0; + /* byte array to receive HID reports from the PC */ + byte led_data[5]; + + /* Implementation of the PUSBListNode */ + EPTYPE_DESCRIPTOR_SIZE epType[1]; + uint8_t protocol; + uint8_t idle; + int getInterface(uint8_t* interfaceCount); + int getDescriptor(USBSetup& setup); + bool setup(USBSetup& setup); + uint8_t getShortName(char *name); +}; + +extern POPNHID_ POPNHID; diff --git a/popnController/popnController.ino b/popnController/popnController.ino index 8af4007..924e365 100644 --- a/popnController/popnController.ino +++ b/popnController/popnController.ino @@ -1,96 +1,61 @@ #define BOUNCE_WITH_PROMPT_DETECTION #include -#if defined(ARDUINO_ARCH_SAM) -#include -#include -#else #include -#endif +#include #include "POPNHID.h" -/* 1 frame (as declared in POPNHID.cpp) on highspeed USB spec is 125µs */ -#define REPORT_DELAY 125 +/* 1 frame (as declared in POPNHID.cpp) on fullspeed USB spec is 1ms */ +#define REPORT_DELAY 1000 #define MILLIDEBOUNCE 15 POPNHID_ POPNHID; /* Buttons + Lights declarations */ -#if defined(ARDUINO_ARCH_SAM) -byte LightPins[] = {A7, CANTX, A8, A9, CANRX, A10, DAC1, A11, DAC0, 14, 15, 16, 17, 18, A6, A5, A4, A3}; //TODO add blocker and counter support -byte ButtonPins[] = {5, 4, 3, 2, 1, 6, 7, 8, 9, 11, 13, 10}; //TODO add reset support (pin 12) and dip (22 24 26 28) -#else -uint8_t LightPins[] = {11,12,13,23,22,21,20,19,18}; -uint8_t ButtonPins[] = {0,1,2,3,4,5,6,7,8,9,10}; -#endif +#define BUT_LED_PIN A0 +#define BUT_NUM_LEDS 9 +#define LEFT_LED_PIN 8 +#define LEFT_NUM_LEDS 9 +#define RIGHT_LED_PIN 9 +#define RIGHT_NUM_LEDS 9 +CRGB but_leds[BUT_NUM_LEDS]; +CRGB left_leds[LEFT_NUM_LEDS]; +CRGB right_leds[RIGHT_NUM_LEDS]; +CRGB but_led_colors[BUT_NUM_LEDS] = {CRGB::White, CRGB::Green, CRGB::Red, CRGB::Green, CRGB::White, CRGB::Yellow, CRGB::Blue, CRGB::Blue, CRGB::Yellow}; +#define PILLAR_BRIGHTNESS 64 +#define BUTTON_BRIGHTNESS 220 +uint8_t NeonPins[] = {A1, A2, A3, A4, A5}; +uint8_t ButtonPins[] = {0, 1, 2, 3, 4, 5, 6, 7, 11, 12, 13}; +uint8_t sysPin = 12; +//this array contains the light offset given buttons 0 to 8 as ref +uint8_t lightOrder[] = {0, 8, 1, 7, 2, 6, 3, 5, 4}; const byte ButtonCount = sizeof(ButtonPins) / sizeof(ButtonPins[0]); -const byte LightCount = sizeof(LightPins) / sizeof(LightPins[0]); +const byte NeonCount = sizeof(NeonPins) / sizeof(NeonPins[0]); + Bounce buttons[ButtonCount]; -#if defined(ARDUINO_ARCH_SAM) -/* Keypad declarations */ -const byte ROWS = 4; -const byte COLS = 3; - -/* -// To use the keypad as the numpad keys (will require to send numlock for it to work) -char numpad[ROWS][COLS] = { - {'\347', '\350', '\351'}, - {'\344', '\345', '\346'}, - {'\341', '\342', '\343'}, - {'\352', ',', '\337'} -}; -*/ - -/* This is to use the toprow keys instead */ -char numpad[ROWS][COLS] = { - {'7', '8', '9'}, - {'4', '5', '6'}, - {'1', '2', '3'}, - {'0', ',', '\337'} -}; - -/* This follows the Pop'n Music cabinet numpad pins order */ -//byte rowPins[ROWS] = {46, 44, 42, 40}; //connect to the row pinouts of the keypad -//byte colPins[COLS] = {48, 50, 52}; //connect to the column pinouts of the keypad - -/* For mini keypad -*/ -byte rowPins[ROWS] = {50, 40, 42, 46}; //connect to the row pinouts of the keypad -byte colPins[COLS] = {48, 52, 44}; //connect to the column pinouts of the keypad - -Keypad kpd = Keypad( makeKeymap(numpad), rowPins, colPins, ROWS, COLS ); -#endif - /* SETUP */ void setup() { // setup I/O for pins for (int i = 0; i < ButtonCount; i++) { - buttons[i] = Bounce(); - buttons[i].attach(ButtonPins[i], INPUT_PULLUP); - buttons[i].interval(MILLIDEBOUNCE); + buttons[i] = Bounce(); + buttons[i].attach(ButtonPins[i], INPUT_PULLUP); + buttons[i].interval(MILLIDEBOUNCE); } - for (int i = 0; i < LightCount; i++) { - pinMode(LightPins[i], OUTPUT); + for (int i = 0; i < NeonCount; i++) { + pinMode(NeonPins[i], OUTPUT); } - -#if defined(ARDUINO_ARCH_SAM) - kpd.setDebounceTime(30); - Keyboard.begin(); - -/* activate numlock if you are not using the toprow keys */ -/* delay(2000); - Keyboard.press(136 + 83); - delay(500); - Keyboard.release(136+83); - */ -#else + + FastLED.addLeds(but_leds, BUT_NUM_LEDS); + FastLED.addLeds(left_leds, LEFT_NUM_LEDS); + FastLED.addLeds(right_leds, RIGHT_NUM_LEDS); + FastLED.setBrightness( BUTTON_BRIGHTNESS ); + uint8_t lightMode; EEPROM.get(0, lightMode); if (lightMode < 0 || lightMode > 3) lightMode = 2; POPNHID.setLightMode(lightMode); -#endif - + //boot animation uint16_t anim[] = {1, 4, 16, 64, 256, 128, 32, 8, 2}; animate(anim, 9, 100); @@ -108,9 +73,9 @@ void loop() { /* BUTTONS */ uint32_t buttonsState = 0; for (int i = 0; i < ButtonCount; i++) { - buttons[i].update(); - int value = buttons[i].read(); - if (value != HIGH){ + buttons[i].update(); + int value = buttons[i].read(); + if (value != HIGH) { buttonsState |= (uint32_t)1 << i; } else { buttonsState &= ~((uint32_t)1 << i); @@ -122,29 +87,27 @@ void loop() { { POPNHID.sendState(buttonsState); lastReport = micros(); - prevButtonsState = buttonsState; - + prevButtonsState = buttonsState; + //check for HID-requested lightmode change POPNHID.updateLightMode(); - } - + } + /* LAMPS */ uint8_t mode = POPNHID.getLightMode(); /* mixed mode will behave sometimes like HID, sometimes like reactive */ - if (mode == 2){ - if ((millis()-POPNHID.getLastHidUpdate()) > 3000) - mode = 0; - else - mode = 1; + if (mode == 2) { + if ((millis() - POPNHID.getLastHidUpdate()) > 3000) + mode = 0; + else + mode = 1; } switch (mode) { /* Reactive mode, locally determined lamp data */ case 0: but_lights(buttonsState & 0x1ff); -#if defined(ARDUINO_ARCH_SAM) reactive_neon(buttonsState & 0x1ff); -#endif break; /* HID mode, only based on received HID data */ case 1: @@ -161,46 +124,17 @@ void loop() { default: break; } - -#if defined(ARDUINO_ARCH_SAM) - /* KEYPAD */ - if (kpd.getKeys()) - { - for (int i = 0; i < LIST_MAX; i++) // Scan the whole key list. - { - if ( kpd.key[i].stateChanged ) // Only find keys that have changed state. - { - switch (kpd.key[i].kstate) { // Report active key state : IDLE, PRESSED, HOLD, or RELEASED - case PRESSED: - Keyboard.press(kpd.key[i].kchar); - break; - case HOLD: - break; - case RELEASED: - Keyboard.release(kpd.key[i].kchar); - break; - case IDLE: - break; - } - - } - } - } -#endif - /* MANUAL LIGHTMODE UPDATE */ if ( buttonsState & 1024 ) { if ( (buttonsState & 2) && (modeChanged == false)) { modeChanged = true; - uint8_t mode = POPNHID.getLightMode()+1; + uint8_t mode = POPNHID.getLightMode() + 1; if (mode > 4) mode = 0; POPNHID.setLightMode(mode); -#if defined(ARDUINO_ARCH_AVR) EEPROM.put(0, mode); -#endif } - else if (!(buttonsState&2)) { + else if (!(buttonsState & 2)) { modeChanged = false; } } @@ -208,40 +142,59 @@ void loop() { /* Light up button lights according to bitfield */ void but_lights(uint16_t lightDesc) { - for (int i = 0; i < 9; i++) { + //conversion de lightDesc + lightDesc = convert_order(lightDesc); + + //allumage + for (int i = 0; i < BUT_NUM_LEDS; i++) { if ((lightDesc >> i) & 1) { - digitalWrite(LightPins[i], HIGH); - } else { - digitalWrite(LightPins[i], LOW); + but_leds[i] = but_led_colors[i]; + } else { + but_leds[i] = 0; } } + FastLED.show(); } /* Light up pillars and top neons according to bitfield */ void neon_lights(uint16_t lightDesc) { - for (int i = 0; i < 9; i++) { + //Top-Lamp + for (int i = 0; i < NeonCount; i++) { if ((lightDesc >> i) & 1) { - digitalWrite(LightPins[i + 9], HIGH); + digitalWrite(NeonPins[i], HIGH); } else { - digitalWrite(LightPins[i + 9], LOW); + digitalWrite(NeonPins[i], LOW); } } + + //LEFT + CRGB left_color = 0; + if ((lightDesc >> 5) & 1) left_color.b += PILLAR_BRIGHTNESS; + if ((lightDesc >> 6) & 1) left_color.r += PILLAR_BRIGHTNESS; + for (int i = 1; i < 8; i++) { + left_leds[i] = left_color; + } + //RIGHT + CRGB right_color = 0; + if ((lightDesc >> 7) & 1) right_color.b += PILLAR_BRIGHTNESS; + if ((lightDesc >> 8) & 1) right_color.r += PILLAR_BRIGHTNESS; + for (int i = 1; i < 8; i++) { + right_leds[i] = right_color; + } + + + FastLED.show(); } /* Display animation on the cab according to a bitfield array */ void animate(uint16_t* tab, uint8_t n, int mswait) { for (int i = 0; i < n; i++) { but_lights(tab[i]); -#if defined(ARDUINO_ARCH_SAM) neon_lights(tab[i]); -#endif delay(mswait); } } -/* ARDUINO DUE ONLY FUNCTIONS */ - -#if defined(ARDUINO_ARCH_SAM) /* Manage pillars and top neons in reactive mode */ uint16_t neon_anim[] = {16, 24, 28, 30, 31, 30, 28, 24}; int neon_anim_index = 0; @@ -257,63 +210,63 @@ unsigned long neonRate = 200; void reactive_neon(uint16_t buttonsState) { uint16_t neons = 0; unsigned long currTime = millis(); - + /* - * SIDE PILLARS - * When pressing any button the side pillars will blink for half a second - * The color is randomly chosen with blue being predominant, red rare and purple super rare - */ + SIDE PILLARS + When pressing any button the side pillars will blink for half a second + The color is randomly chosen with blue being predominant, red rare and purple super rare + */ if ( buttonsState != prevState ) { - if ( buttonsState != 0 ){ - long randNumber = random(21); - if (randNumber == 0) - { - pillar_state_index = 3; + if ( buttonsState != 0 ) { + long randNumber = random(21); + if (randNumber == 0) + { + pillar_state_index = 3; + } + else if (randNumber < 3) + { + pillar_state_index = 1; + } else { + pillar_state_index = 2; + } + pillar_lit = true; + if (buttonsState != 0) lastButtonAction = currTime; } - else if (randNumber < 3) - { - pillar_state_index = 1; - } else { - pillar_state_index = 2; - } - pillar_lit = true; - if (buttonsState != 0) lastButtonAction = currTime; - } - prevState = buttonsState; - } else { /* no state change, continue to blink for 50ms */ - if (currTime - lastBlink > 50) { + prevState = buttonsState; + } else { /* no state change, continue to blink for 50ms */ + if (currTime - lastBlink > 50) { pillar_lit = !pillar_lit; lastBlink = currTime; } - if (currTime - lastButtonAction > 500) { + if (currTime - lastButtonAction > 500) { pillar_state_index = 0; } - } + } -if (pillar_lit) - neons |= pillar_state[pillar_state_index]; + if (pillar_lit) + neons |= pillar_state[pillar_state_index]; /* - * Adjusting top neon animation speed (should go faster when you hit buttons quickly) - */ - actionRate = currTime - lastButtonAction; - - if (15*actionRate < neonRate) + Adjusting top neon animation speed (should go faster when you hit buttons quickly) + */ + actionRate = currTime - lastButtonAction; + + if (15 * actionRate < neonRate) neonRate *= 0.99995; - else if (actionRate > 10*neonRate){ - neonRate = neonRate*1.01; + else if (actionRate > 10 * neonRate) { + neonRate = neonRate * 1.01; if (neonRate < 100) neonRate++; - } - if (neonRate > 400) + } + if (neonRate > 400) neonRate = 400; - if (neonRate < 40) + if (neonRate < 40) neonRate = 40; - + /* - * Cycling through the top neon animation - */ + Cycling through the top neon animation + */ if ((currTime - lastNeonUpdate) > neonRate) { neon_anim_index++; @@ -324,8 +277,18 @@ if (pillar_lit) neons |= neon_anim[neon_anim_index]; /* - * Light the leds - */ + Light the leds + */ neon_lights(neons); } -#endif + +/* BARTOP ONLY FUNCTIONS */ +uint16_t convert_order(uint16_t lightDesc) { + uint16_t res = 0; + for (int i = 0; i < BUT_NUM_LEDS; i++) { + if ((lightDesc >> i) & 1) { + res |= 1 << (lightOrder[i]); + } + } + return res; +}