Config now works!

This commit is contained in:
William Toohey 2015-11-14 21:01:55 +10:00
parent 6d85ad42bd
commit 6738ab1dc1
6 changed files with 152 additions and 110 deletions

View File

@ -0,0 +1,38 @@
#include <Config.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
static tatacon_config_t defaults PROGMEM = {
.switches = {
HID_KEYBOARD_SC_X,
HID_KEYBOARD_SC_Z,
HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN,
HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK },
.ledsOn = true,
.debounce = 20
};
uint8_t firstRun EEMEM; // init to 255
tatacon_config_t eeConfig EEMEM;
tatacon_config_t tataConfig;
void InitConfig(void) {
if (eeprom_read_byte(&firstRun) != 42) { // store defaults
memcpy_P(&tataConfig, &defaults, sizeof(tatacon_config_t));
eeprom_write_block(&tataConfig, &eeConfig, sizeof(tatacon_config_t));
eeprom_write_byte(&firstRun, 42); // defaults set
}
eeprom_read_block(&tataConfig, &eeConfig, sizeof(tatacon_config_t));
}
void SetConfig(uint8_t* config) {
for(int i = 0; i < 4; i++) {
tataConfig.switches[i] = config[i];
}
tataConfig.ledsOn = config[4];
tataConfig.debounce = config[5];
eeprom_write_block(&tataConfig, &eeConfig, sizeof(tatacon_config_t));
}

View File

@ -0,0 +1,22 @@
#ifndef _CONFIG_H
#define _CONFIG_H
#include <stdint.h>
#include <stdbool.h>
#include <LUFA/Drivers/USB/USB.h>
#define TATACON_CONFIG_BYTES 8
typedef struct {
// SWITCH ORDER: CenterLeft, RimLeft, CenterRight, RimRight
uint8_t switches[4];
bool ledsOn;
uint8_t debounce;
} tatacon_config_t;
extern tatacon_config_t tataConfig;
extern void InitConfig(void);
extern void SetConfig(uint8_t* config);
#endif

View File

@ -51,11 +51,16 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] =
HID_RI_USAGE(8, 0x02), /* Vendor Usage 2 */
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_REPORT_COUNT(16, (sizeof(uint16_t) + SPM_PAGESIZE)),
//HID_RI_REPORT_SIZE(8, 1),
//HID_RI_REPORT_COUNT(8, TATACON_CONFIG_BYTES),
HID_RI_REPORT_SIZE(8, 8),
HID_RI_REPORT_COUNT(8, TATACON_CONFIG_BYTES),
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
HID_RI_USAGE(8, 0x02), /* Vendor Usage 2 */
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
HID_RI_REPORT_SIZE(8, 8),
HID_RI_REPORT_COUNT(8, TATACON_CONFIG_BYTES),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
HID_RI_END_COLLECTION(0),
};
@ -194,7 +199,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.EndpointAddress = GENERIC_EPADDR,
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = GENERIC_EPSIZE,
.PollingIntervalMS = 20
.PollingIntervalMS = 255
},
};
@ -214,10 +219,10 @@ const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor.
*/
const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"Tatacon to USB");
const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"Tatacon to USB Converter");
const USB_Descriptor_String_t PROGMEM ConfigString = USB_STRING_DESCRIPTOR(L"Tatacon Configuration");
const USB_Descriptor_String_t PROGMEM ConfigString = USB_STRING_DESCRIPTOR(L"Tatacon Config");
const USB_Descriptor_String_t PROGMEM TataconString = USB_STRING_DESCRIPTOR(L"Tatacon");

View File

@ -41,7 +41,7 @@
#include <LUFA/Drivers/USB/USB.h>
#define TATACON_CONFIG_BYTES 8
#include "Config.h"
/* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
@ -94,7 +94,7 @@
/** Size in bytes of the Keyboard HID reporting IN endpoint. */
#define KEYBOARD_EPSIZE 8
#define GENERIC_EPSIZE 64
#define GENERIC_EPSIZE TATACON_CONFIG_BYTES
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,

View File

@ -36,6 +36,7 @@
#include "Keyboard.h"
#include "i2cmaster.h"
#include "Config.h"
#define LED_DIR DDRD
#define LED_PORT PORTD
@ -44,9 +45,11 @@
#define SET(port, pin) port |= _BV(pin)
#define CLEAR(port, pin) port &= ~_BV(pin)
#define TOGGLE(port, pin) port ^= _BV(pin)
/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
static uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)];
static uint8_t PrevGenericHIDReportBuffer[TATACON_CONFIG_BYTES];
/** LUFA HID Class driver interface configuration and state information. This structure is
* passed to all HID Class driver functions, so that multiple instances of the same class
@ -68,6 +71,21 @@ USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
},
};
USB_ClassInfo_HID_Device_t Generic_HID_Interface =
{
.Config =
{
.InterfaceNumber = INTERFACE_ID_Generic,
.ReportINEndpoint =
{
.Address = GENERIC_EPADDR,
.Size = GENERIC_EPSIZE,
.Banks = 1,
},
.PrevReportINBuffer = PrevGenericHIDReportBuffer,
.PrevReportINBufferSize = sizeof(PrevGenericHIDReportBuffer),
},
};
typedef struct {
// optimise data sending
@ -75,12 +93,7 @@ typedef struct {
uint8_t lastReport;
} switch_t;
// SWITCH ORDER: CenterLeft, RimLeft, CenterRight, RimRight
static switch_t switches[4];
static const uint8_t switch_mapping[] = {HID_KEYBOARD_SC_X,
HID_KEYBOARD_SC_Z,
HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN,
HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK };
static uint8_t switchesChanged = 1;
static uint8_t nunchuckReady = 0;
@ -97,6 +110,13 @@ void Nunchuck_gone(void) {
// Turn LEDs on until it returns
SET(LED_PORT, DON_LED_PIN);
SET(LED_PORT, KAT_LED_PIN);
// Clear structs
for(int i = 0; i < 4; i++) {
switches[i].state = 0;
if(switches[i].lastReport) {
switchesChanged = 1;
}
}
}
void Nunchuck_Init(void) {
// try to say hello
@ -158,11 +178,13 @@ int main(void)
{
uint8_t i;
// Clear structs
for(i = 0; i < 2; i++) {
for(i = 0; i < 4; i++) {
switches[i].state = 0;
switches[i].lastReport = 0;
}
InitConfig();
SetupHardware();
GlobalInterruptEnable();
@ -170,6 +192,7 @@ int main(void)
for (;;)
{
HID_Device_USBTask(&Keyboard_HID_Interface);
HID_Device_USBTask(&Generic_HID_Interface);
USB_USBTask();
}
}
@ -184,9 +207,11 @@ void SetupHardware()
/* Hardware Initialization */
SET(LED_DIR, DON_LED_PIN);
SET(LED_DIR, KAT_LED_PIN);
// Turn them on until we init with the nunchuck
SET(LED_PORT, DON_LED_PIN);
SET(LED_PORT, KAT_LED_PIN);
if(tataConfig.ledsOn) {
// Turn them on until we init with the nunchuck
SET(LED_PORT, DON_LED_PIN);
SET(LED_PORT, KAT_LED_PIN);
}
i2c_init();
Nunchuck_Init();
USB_Init();
@ -209,38 +234,47 @@ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDIn
uint16_t* const ReportSize)
{
uint8_t i;
if(ReportType != HID_REPORT_ITEM_In) {
*ReportSize = 0;
return false;
}
if (HIDInterfaceInfo == &Keyboard_HID_Interface) {
if(ReportType == HID_REPORT_ITEM_In) {
update_switches();
if(!switchesChanged) {
return false;
}
CLEAR(LED_PORT, DON_LED_PIN);
CLEAR(LED_PORT, KAT_LED_PIN);
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
for(i = 0; i < 4; i++) {
KeyboardReport->KeyCode[i] = switches[i].state ? switch_mapping[i] : 0;
switches[i].lastReport = switches[i].state;
// Update blinkenlights
if(switches[i].state) {
if(i % 2) { // odd indexes are kat, even don
SET(LED_PORT, KAT_LED_PIN);
} else {
SET(LED_PORT, DON_LED_PIN);
}
update_switches();
if(!switchesChanged) {
*ReportSize = 0;
return false;
}
CLEAR(LED_PORT, DON_LED_PIN);
CLEAR(LED_PORT, KAT_LED_PIN);
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
for(i = 0; i < 4; i++) {
KeyboardReport->KeyCode[i] = switches[i].state ? tataConfig.switches[i] : 0;
switches[i].lastReport = switches[i].state;
// Update blinkenlights
if(switches[i].state) {
if(i % 2 && tataConfig.ledsOn) { // odd indexes are kat, even don
SET(LED_PORT, KAT_LED_PIN);
} else {
SET(LED_PORT, DON_LED_PIN);
}
}
*ReportSize = sizeof(USB_KeyboardReport_Data_t);
switchesChanged = 0;
return true;
}
*ReportSize = sizeof(USB_KeyboardReport_Data_t);
switchesChanged = 0;
return true;
} else if(HIDInterfaceInfo == &Generic_HID_Interface) {
uint8_t* ConfigReport = (uint8_t*)ReportData;
memcpy(ConfigReport, &tataConfig, sizeof(tatacon_config_t));
*ReportSize = TATACON_CONFIG_BYTES;
return true;
}
*ReportSize = 0;
return false;
}
@ -259,7 +293,10 @@ void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDI
const void* ReportData,
const uint16_t ReportSize)
{
if(HIDInterfaceInfo == &Generic_HID_Interface && ReportType == HID_REPORT_ITEM_Out) {
uint8_t* ConfigReport = (uint8_t*)ReportData;
SetConfig(ConfigReport);
}
}
@ -279,7 +316,7 @@ void EVENT_USB_Device_Disconnect(void)
void EVENT_USB_Device_ConfigurationChanged(void)
{
HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface);
Endpoint_ConfigureEndpoint(GENERIC_EPADDR, EP_TYPE_INTERRUPT, GENERIC_EPSIZE, 1);
HID_Device_ConfigureEndpoints(&Generic_HID_Interface);
USB_Device_EnableSOFEvents();
}
@ -288,72 +325,12 @@ void EVENT_USB_Device_ConfigurationChanged(void)
void EVENT_USB_Device_ControlRequest(void)
{
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
/* Ignore any requests that aren't directed to the HID interface */
if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) !=
(REQTYPE_CLASS | REQREC_INTERFACE))
{
return;
}
/* Process HID specific control requests */
switch (USB_ControlRequest.bRequest)
{
case HID_REQ_SetReport:
/*Endpoint_ClearSETUP();
// Wait until the command has been sent by the host
while (!(Endpoint_IsOUTReceived()));
// Read in the write destination address
#if (FLASHEND > 0xFFFF)
uint32_t PageAddress = ((uint32_t)Endpoint_Read_16_LE() << 8);
#else
uint16_t PageAddress = Endpoint_Read_16_LE();
#endif
// Check if the command is a program page command, or a start application command
#if (FLASHEND > 0xFFFF)
if ((uint16_t)(PageAddress >> 8) == COMMAND_STARTAPPLICATION)
#else
if (PageAddress == COMMAND_STARTAPPLICATION)
#endif
{
RunBootloader = false;
}
else
{
boot_page_erase(PageAddress);
boot_spm_busy_wait();
for (uint8_t PageWord = 0; PageWord < (SPM_PAGESIZE / 2); PageWord++)
{
// Check if endpoint is empty - if so clear it and wait until ready for next packet
if (!(Endpoint_BytesInEndpoint()))
{
Endpoint_ClearOUT();
while (!(Endpoint_IsOUTReceived()));
}
boot_page_fill(PageAddress + ((uint16_t)PageWord << 1), Endpoint_Read_16_LE());
}
boot_page_write(PageAddress);
boot_spm_busy_wait();
boot_rww_enable();
}
Endpoint_ClearOUT();
Endpoint_ClearStatusStage();*/
break;
}
HID_Device_ProcessControlRequest(&Generic_HID_Interface);
}
/** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void)
{
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
HID_Device_MillisecondElapsed(&Generic_HID_Interface);
}

View File

@ -18,7 +18,7 @@ F_CPU = 8000000
F_USB = $(F_CPU)
OPTIMIZATION = s
TARGET = Keyboard
SRC = $(TARGET).c Descriptors.c i2cmaster.S $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
SRC = $(TARGET).c Descriptors.c i2cmaster.S Config.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
LUFA_PATH = ../LUFA
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/
LD_FLAGS =