Fix libusb connectivity and add more config stuff

This commit is contained in:
William Toohey
2017-02-01 17:38:43 +10:00
parent 681344f167
commit 9e5925118c
6 changed files with 166 additions and 114 deletions
+1 -2
View File
@@ -14,8 +14,7 @@ static sdvx_config_t defaults PROGMEM = {
HID_KEYBOARD_SC_C,
HID_KEYBOARD_SC_M,
HID_KEYBOARD_SC_ENTER},
.ledsOn = true,
.debounce = 30,
//.ledsOn = true,
.macroClick = HID_KEYBOARD_SC_KEYPAD_PLUS,
.macroPin = {HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT,
HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT,
+41 -7
View File
@@ -4,32 +4,66 @@
#include <stdint.h>
#include <stdbool.h>
#include <LUFA/Drivers/USB/USB.h>
#include "LED.h"
// 7 gameplay switches + macro combo switch
#define SWITCH_COUNT 8
#define MAGIC_RESET_NUMBER 42
// divide by 10 for actual version
#define FIRMWARE_VERSION 1
// not configurable since they're all the same switches
#define SWITCH_DEBOUNCE 30
typedef struct {
// used to reboot into programming mode
uint8_t reboot;
uint8_t version;
// SWITCH ORDER: A-D, FXL-R, START
uint8_t switches[SWITCH_COUNT];
bool ledsOn;
uint8_t debounce;
RGB_t btColour;
RGB_t fxColour;
RGB_t knobColours[2];
bool lightsOn;
bool hidLights;
bool keyLights;
bool knobLights;
uint8_t lightPattern;
// When tapping or long-pressing the macro key
uint8_t macroClick;
uint8_t macroPin[4];
} sdvx_config_t;
// + 1 for some reason
// TODO: what is the reason
#define CONFIG_BYTES sizeof(sdvx_config_t)
typedef struct {
uint8_t version;
uint16_t serial;
} version_t;
typedef enum {
GETCONFIG = 1,
SETCONFIG = 2,
RESET = MAGIC_RESET_NUMBER
} command_action_t;
typedef enum {
RESPOND = 0,
IGNORE,
REBOOT
} command_response_t;
typedef struct {
command_action_t command;
union {
sdvx_config_t config;
version_t version;
} data;
} command_t;
#define COMMAND_BYTES sizeof(command_t)
extern sdvx_config_t sdvxConfig;
extern void InitConfig(void);
extern void SetConfig(sdvx_config_t* config);
extern command_response_t HandleConfig(uint8_t* buffer);
#endif
+38 -39
View File
@@ -129,7 +129,45 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.MaxPowerConsumption = USB_CONFIG_POWER_MA(500)
},
.Config_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = INTERFACE_ID_Config,
.AlternateSetting = 0,
.TotalEndpoints = 2,
.Class = 0xFF,
.SubClass = 0xFF,
.Protocol = 0xFF,
.InterfaceStrIndex = STRING_ID_Config
},
.Config_DataInEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = CONFIG_IN_EPADDR,
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CONFIG_EPSIZE,
// ignored but required
.PollingIntervalMS = 0x05
},
.Config_DataOutEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = CONFIG_OUT_EPADDR,
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CONFIG_EPSIZE,
// ignored but required
.PollingIntervalMS = 0x05
},
.HID1_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@@ -240,44 +278,6 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.EndpointSize = LED_EPSIZE,
.PollingIntervalMS = 255
},
.Config_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = INTERFACE_ID_Config,
.AlternateSetting = 0,
.TotalEndpoints = 2,
.Class = 0xFF,
.SubClass = 0xFF,
.Protocol = 0xFF,
.InterfaceStrIndex = STRING_ID_Config
},
.Config_DataInEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = CONFIG_IN_EPADDR,
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CONFIG_EPSIZE,
// ignored but required
.PollingIntervalMS = 0x05
},
.Config_DataOutEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = CONFIG_OUT_EPADDR,
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CONFIG_EPSIZE,
// ignored but required
.PollingIntervalMS = 0x05
}
};
@@ -332,7 +332,6 @@ void USB_Process_BOS(void) {
USB_ControlRequest.bmRequestType != (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE)) {
return;
}
led_set_all(16,16,16);
switch(USB_ControlRequest.bRequest) {
case WEBUSB_ID:
switch(USB_ControlRequest.wIndex) {
+17 -17
View File
@@ -52,7 +52,12 @@
typedef struct
{
USB_Descriptor_Configuration_Header_t Config;
// Config interface as we can't talk to composite directly
USB_Descriptor_Interface_t Config_Interface;
USB_Descriptor_Endpoint_t Config_DataInEndpoint;
USB_Descriptor_Endpoint_t Config_DataOutEndpoint;
// Keyboard HID Interface
USB_Descriptor_Interface_t HID1_Interface;
USB_HID_Descriptor_HID_t HID1_KeyboardHID;
@@ -67,21 +72,16 @@
USB_Descriptor_Interface_t HID3_Interface;
USB_HID_Descriptor_HID_t HID3_LEDHID;
USB_Descriptor_Endpoint_t HID3_ReportINEndpoint;
// Config interface as we can't talk to composite directly
USB_Descriptor_Interface_t Config_Interface;
USB_Descriptor_Endpoint_t Config_DataInEndpoint;
USB_Descriptor_Endpoint_t Config_DataOutEndpoint;
} USB_Descriptor_Configuration_t;
/** Enum for the device interface descriptor IDs within the device.
*/
enum InterfaceDescriptors_t
{
INTERFACE_ID_Keyboard = 0, /**< Keyboard interface descriptor ID */
INTERFACE_ID_Mouse = 1, /**< Mouse interface descriptor ID */
INTERFACE_ID_LED = 2, /**< LED interface descriptor ID */
INTERFACE_ID_Config = 3 /**< Config interface descriptor ID */
INTERFACE_ID_Config = 0, /**< Config interface descriptor ID */
INTERFACE_ID_Keyboard = 1, /**< Keyboard interface descriptor ID */
INTERFACE_ID_Mouse = 2, /**< Mouse interface descriptor ID */
INTERFACE_ID_LED = 3, /**< LED interface descriptor ID */
};
/** Enum for the device string descriptor IDs within the device. Each string descriptor should
@@ -104,19 +104,19 @@
};
/* Macros: */
#define KEYBOARD_EPADDR (ENDPOINT_DIR_IN | 1)
#define MOUSE_IN_EPADDR (ENDPOINT_DIR_IN | 2)
#define LED_EPADDR (ENDPOINT_DIR_IN | 3)
#define CONFIG_IN_EPADDR (ENDPOINT_DIR_IN | 4)
#define CONFIG_IN_EPADDR (ENDPOINT_DIR_IN | 1)
#define CONFIG_OUT_EPADDR (ENDPOINT_DIR_OUT | 5)
#define KEYBOARD_EPADDR (ENDPOINT_DIR_IN | 2)
#define MOUSE_IN_EPADDR (ENDPOINT_DIR_IN | 3)
#define LED_EPADDR (ENDPOINT_DIR_IN | 4)
#define KEYBOARD_EPSIZE SWITCH_COUNT + 2
#define MOUSE_EPSIZE 8
#define LED_EPSIZE LED_TOTAL_COUNT
// MUST be 8, 16, 32 or 64 bytes
#define CONFIG_EPSIZE CONFIG_BYTES <= 8 ? 8 : \
CONFIG_BYTES <= 16 ? 16 : \
CONFIG_BYTES <= 32 ? 32 : 64 // if it's larger than 64 bytes, you're out of luck
#define CONFIG_EPSIZE COMMAND_BYTES <= 8 ? 8 : \
COMMAND_BYTES <= 16 ? 16 : \
COMMAND_BYTES <= 32 ? 32 : 64 // if it's larger than 64 bytes, you're out of luck
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+69 -40
View File
@@ -5,7 +5,14 @@
#include "LEDPatterns.h"
#include "Macro.h"
#define READ_SWITCH(x) (!(*pins[switches[x].switchPort] & _BV(switches[x].switchPin)))
#define LOAD_SWITCH(source, sourceBit, result, resultBit) result |= !((source) & _BV(sourceBit)) << resultBit
// B 0,1
#define SWITCH_MASKB 0b00000011
// C 1,2
#define SWITCH_MASKC 0b00000110
// D 4,5,6,7
#define SWITCH_MASKD 0b11110000
#define MAGIC_BOOT_KEY 0xDEADBE7A
// offset * word size
#define BOOTLOADER_START_ADDRESS (0x1c00 * 2)
@@ -83,20 +90,7 @@ USB_ClassInfo_HID_Device_t LED_HID_Interface =
},
};
static volatile uint8_t *ports[] = {&PORTB, &PORTC, &PORTD};
static volatile uint8_t *pins[] = {&PINB, &PINC, &PIND};
static volatile uint8_t *ddrs[] = {&DDRB, &DDRC, &DDRD};
static switch_t switches[SWITCH_COUNT] = {
{B, 1}, // A
{D, 7}, // B
{D, 5}, // C
{D, 4}, // D
{B, 0}, // FX L
{D, 6}, // FX R
{C, 2}, // START
{C, 1} // Macro key
};
static switch_t switches[SWITCH_COUNT];
static uint8_t switchesChanged = 1;
// Set to max already so we have our init flash
@@ -126,16 +120,38 @@ void RebootToBootloader(void) {
while(1);
}
/* This is verbose and annoying but the nice method wastes 30 bytes of RAM */
uint8_t load_switches(void) {
uint8_t tmp;
uint8_t result = 0;
tmp = PINB;
LOAD_SWITCH(tmp, 1, result, 0); // PINB1, A
LOAD_SWITCH(tmp, 0, result, 4); // PINB0, FX L
tmp = PINC;
LOAD_SWITCH(tmp, 2, result, 6); // PINC2, START
LOAD_SWITCH(tmp, 1, result, 7); // PINC1, MACRO
tmp = PIND;
LOAD_SWITCH(tmp, 7, result, 1); // PIND7, B
LOAD_SWITCH(tmp, 5, result, 2); // PIND5, C
LOAD_SWITCH(tmp, 4, result, 3); // PIND4, D
LOAD_SWITCH(tmp, 6, result, 5); // PIND6, FX L
return result;
}
void update_switches(void) {
uint8_t i, newState;
uint8_t switchRead = load_switches();
for(i = 0; i < SWITCH_COUNT; i++) {
newState = READ_SWITCH(i);
newState = switchRead & 1;
if(!switches[i].debounce && newState != switches[i].lastReport) {
switches[i].state = newState;
switches[i].debounce = sdvxConfig.debounce;
switches[i].debounce = SWITCH_DEBOUNCE;
switchesChanged = 1;
}
switchRead >>= 1;
}
}
@@ -159,17 +175,27 @@ int main(void)
HID_Device_USBTask(&LED_HID_Interface);
USB_USBTask();
//uint8_t ReceivedData[VENDOR_IO_EPSIZE];
//memset(ReceivedData, 0x00, sizeof(ReceivedData));
//
Endpoint_SelectEndpoint(CONFIG_OUT_EPADDR);
if (Endpoint_IsOUTReceived()) {
// Endpoint_Read_Stream_LE(ReceivedData, VENDOR_IO_EPSIZE, NULL);
uint8_t ReceivedData[CONFIG_EPSIZE];
Endpoint_Read_Stream_LE(ReceivedData, CONFIG_EPSIZE, NULL);
Endpoint_ClearOUT();
//
// Endpoint_SelectEndpoint(VENDOR_IN_EPADDR);
// Endpoint_Write_Stream_LE(ReceivedData, VENDOR_IO_EPSIZE, NULL);
// Endpoint_ClearIN();
command_response_t respond = HandleConfig(ReceivedData);
switch(respond) {
// we are returning the requested data
case RESPOND:
Endpoint_SelectEndpoint(CONFIG_IN_EPADDR);
Endpoint_Write_Stream_LE(ReceivedData, CONFIG_EPSIZE, NULL);
Endpoint_ClearIN();
break;
case REBOOT:
RebootToBootloader();
break;
// no data to return
default:
break;
}
}
}
}
@@ -187,16 +213,20 @@ void SetupHardware()
switches[i].state = 0;
switches[i].lastReport = 0;
switches[i].debounce = 0;
// setup switches to be inputs
*ddrs[switches[i].switchPort] &= ~_BV(switches[i].switchPin);
// with internal pullups
*ports[switches[i].switchPort] |= _BV(switches[i].switchPin);
}
// Inputs
DDRB &= ~SWITCH_MASKB;
DDRC &= ~SWITCH_MASKC;
DDRD &= ~SWITCH_MASKD;
// Pullups
PORTB |= SWITCH_MASKB;
PORTC |= SWITCH_MASKC;
// RESET has its own pullup
*ports[switches[SWITCH_COUNT-1].switchPort] &= ~_BV(switches[SWITCH_COUNT-1].switchPin);
PORTC &= ~_BV(1);
PORTD |= SWITCH_MASKD;
// RESET held while plugging in
if(READ_SWITCH(SWITCH_COUNT-1)) {
if(!(PINC & _BV(1))) {
RebootToBootloader();
}
@@ -246,9 +276,9 @@ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDIn
switches[i].lastReport = switches[i].state;
// Update blinkenlights
if(switches[i].state) {
if(sdvxConfig.ledsOn) {
// TODO
}
//if(sdvxConfig.ledsOn) {
// // TODO
//}
}
}
@@ -272,7 +302,6 @@ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDIn
}
*ReportSize = 0;
return false;
}
/** HID class driver callback function for the processing of HID reports from the host.
@@ -321,17 +350,17 @@ void EVENT_USB_Device_Connect(void)
/** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void)
{
led_set_all(0,0,0);
}
/** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void)
{
Endpoint_ConfigureEndpoint(CONFIG_IN_EPADDR, EP_TYPE_BULK, CONFIG_EPSIZE, 1);
Endpoint_ConfigureEndpoint(CONFIG_OUT_EPADDR, EP_TYPE_BULK, CONFIG_EPSIZE, 1);
HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface);
HID_Device_ConfigureEndpoints(&Mouse_HID_Interface);
HID_Device_ConfigureEndpoints(&LED_HID_Interface);
Endpoint_ConfigureEndpoint(CONFIG_IN_EPADDR, EP_TYPE_BULK, CONFIG_EPSIZE, 1);
Endpoint_ConfigureEndpoint(CONFIG_OUT_EPADDR, EP_TYPE_BULK, CONFIG_EPSIZE, 1);
USB_Device_EnableSOFEvents();
}
@@ -340,9 +369,9 @@ void EVENT_USB_Device_ConfigurationChanged(void)
void EVENT_USB_Device_ControlRequest(void)
{
USB_Process_BOS();
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
HID_Device_ProcessControlRequest(&Mouse_HID_Interface);
HID_Device_ProcessControlRequest(&LED_HID_Interface);
HID_Device_ProcessControlRequest(&LED_HID_Interface);
}
/** Event handler for the USB device Start Of Frame event. */
-9
View File
@@ -49,16 +49,7 @@
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Platform/Platform.h>
// NOTE: atemga16u2 does not have a PORTA
typedef enum {
B = 0,
C,
D
} port_t;
typedef struct {
port_t switchPort;
uint8_t switchPin;
uint8_t state;
uint8_t lastReport;
uint8_t debounce;