Skip to content

Instantly share code, notes, and snippets.

@strider-
Created March 1, 2015 17:23
Show Gist options
  • Save strider-/af05f48197dd6a7ef32e to your computer and use it in GitHub Desktop.
Save strider-/af05f48197dd6a7ef32e to your computer and use it in GitHub Desktop.
#include "Keyboard.h"
uint8_t inputs[8] = { PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7 };
/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
static uint8_t PrevKeyboardHIDReportBuffer[MAX(sizeof(USB_KeyboardReport_Data_t), sizeof(USB_MediaReport_Data_t))];
/** 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
* within a device can be differentiated from one another.
*/
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
{
.Config =
{
.InterfaceNumber = INTERFACE_ID_Keyboard,
.ReportINEndpoint =
{
.Address = KEYBOARD_EPADDR,
.Size = KEYBOARD_EPSIZE,
.Banks = 1,
},
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
.PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
},
};
/** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop.
*/
int main(void)
{
SetupHardware();
//LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
GlobalInterruptEnable();
for (;;)
{
HID_Device_USBTask(&Keyboard_HID_Interface);
USB_USBTask();
}
}
/** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware()
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
/* Disable clock division */
clock_prescale_set(clock_div_1);
/* Hardware Initialization */
// Joystick_Init();
// LEDs_Init();
//Buttons_Init();
for(uint8_t i = 0; i < sizeof(inputs); i++)
{
DDRD &= ~(_BV(inputs[i]));
PORTD |= _BV(inputs[i]);
}
USB_Init();
}
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void)
{
//LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void)
{
//LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void)
{
bool ConfigSuccess = true;
ConfigSuccess &= HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface);
USB_Device_EnableSOFEvents();
//LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
}
/** Event handler for the library USB Control Request reception event. */
void EVENT_USB_Device_ControlRequest(void)
{
HID_Device_ProcessControlRequest(&Keyboard_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 class driver callback function for the creation of HID reports to the host.
*
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
* \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature
* \param[out] ReportData Pointer to a buffer where the created report should be stored
* \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent)
*
* \return Boolean \c true to force the sending of the report, \c false to let the library determine if it needs to be sent
*/
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
uint8_t* const ReportID,
const uint8_t ReportType,
void* ReportData,
uint16_t* const ReportSize)
{
if(ReportType == HID_REPORT_ITEM_In)
{
for(uint8_t i = 0; i < sizeof(inputs); i++)
{
if((PIND & _BV(inputs[i])) == 0)
{
ButtonData_t* buttonData = (ButtonData_t*)malloc(sizeof(ButtonData_t));
eeprom_read_block(buttonData, (void*)(sizeof(ButtonData_t) * i), sizeof(ButtonData_t));
if((buttonData->ButtonIndex & 0x80) == 0)
{
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
KeyboardReport->KeyCode[0] = buttonData->Scancodes[0];
KeyboardReport->Modifier = buttonData->Modifier;
*ReportID = HID_REPORTID_KeyboardReport;
*ReportSize = sizeof(USB_KeyboardReport_Data_t);
}
else
{
USB_MediaReport_Data_t* MediaReport = (USB_MediaReport_Data_t*)ReportData;
uint8_t code = buttonData->Scancodes[0];
MediaReport->Mute = (code == HID_KEYBOARD_SC_MEDIA_MUTE);
MediaReport->PlayPause = (code == HID_KEYBOARD_SC_MEDIA_PLAY);
MediaReport->VolumeUp = (code == HID_KEYBOARD_SC_MEDIA_VOLUME_UP);
MediaReport->VolumeDown = (code == HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN);
MediaReport->PreviousTrack = (code == HID_KEYBOARD_SC_MEDIA_PREVIOUS_TRACK);
MediaReport->NextTrack = (code == HID_KEYBOARD_SC_MEDIA_NEXT_TRACK);
*ReportID = HID_REPORTID_ConsumerReport;
*ReportSize = sizeof(USB_MediaReport_Data_t);
}
free(buttonData);
}
}
}
return false;
}
/** HID class driver callback function for the processing of HID reports from the host.
*
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in] ReportID Report ID of the received report from the host
* \param[in] ReportType The type of report that the host has sent, either HID_REPORT_ITEM_Out or HID_REPORT_ITEM_Feature
* \param[in] ReportData Pointer to a buffer where the received report has been stored
* \param[in] ReportSize Size in bytes of the received HID report
*/
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
const uint8_t ReportID,
const uint8_t ReportType,
const void* ReportData,
const uint16_t ReportSize)
{
if(ReportType == HID_REPORT_ITEM_Feature && ReportID == HID_REPORTID_KeyboardReport)
{
ButtonData_t* buttonData = (ButtonData_t*)ReportData;
eeprom_update_block(buttonData, (void*)(sizeof(ButtonData_t) * (buttonData->ButtonIndex &~ 0x80)), sizeof(ButtonData_t));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment