Joystick.c
#include "Joystick.h"
unsigned int map[28+9]={
SWITCH_Y,SWITCH_B,SWITCH_A,SWITCH_X,SWITCH_L,SWITCH_R,SWITCH_ZL,SWITCH_ZR,SWITCH_MINUS,
SWITCH_PLUS,SWITCH_LCLICK,SWITCH_RCLICK,SWITCH_HOME,SWITCH_CAPTURE,
~SWITCH_Y,~SWITCH_B,~SWITCH_A,~SWITCH_X,~SWITCH_L,~SWITCH_R,~SWITCH_ZL,~SWITCH_ZR,~SWITCH_MINUS,
~SWITCH_PLUS,~SWITCH_LCLICK,~SWITCH_RCLICK,~SWITCH_HOME,~SWITCH_CAPTURE,
HAT_TOP,HAT_TOP_RIGHT,HAT_RIGHT,HAT_BOTTOM_RIGHT,HAT_BOTTOM,HAT_BOTTOM_LEFT,HAT_LEFT,HAT_TOP_LEFT,
HAT_CENTER,
};
int main(void) {
SetupHardware();
GlobalInterruptEnable();
for (;;)
{
receiveCmd();
HID_Task(); //read/write HID event
USB_USBTask();//api call
}
}
int16_t curCmd = -1;
int mCnt = 1;
unsigned int stickCnt = 0;
void receiveCmd(){
int16_t c;
if(tt_Serial_IsCharReceived())
{
c = (char)tt_Serial_ReceiveByte();
curCmd = c;
if(curCmd>=60 && curCmd<=63){
while(true){
if(tt_Serial_IsCharReceived()){
stickCnt = (unsigned int)tt_Serial_ReceiveByte();
break;
}
}
}
tt_Serial_SendString("OK\n");
}
}
void SetupHardware(void) {
//disable watchdog if enabled by bootloader/fuses.
MCUSR &= ~(1 << WDRF);
wdt_disable();
//disable clock division before initializing the USB hardware.
clock_prescale_set(clock_div_1);
//Serial init
tt_Serial_Init(9600, false);
tt_Serial_SendString("Test String start\r\n");
// The USB stack should be initialized last.
USB_Init();
}
unsigned int lastLX=STICK_CENTER,lastLY=STICK_CENTER,lastRX=STICK_CENTER,lastRY=STICK_CENTER;
int first = 0;
// Prepare the next report for the host.
void GetNextReport(USB_JoystickReport_Input_t* const ReportData) {
memset(ReportData, 0, sizeof(USB_JoystickReport_Input_t));
ReportData->LX = lastLX;
ReportData->LY = lastLY;
ReportData->RX = lastRX;
ReportData->RY = lastRY;
ReportData->HAT = HAT_CENTER;
if(curCmd>=0){
if(curCmd<14) ReportData->Button |= map[curCmd];
if(curCmd>=14 && curCmd<28) ReportData->Button &= ~map[curCmd];
if(curCmd>=28 && curCmd<37) ReportData->HAT = map[curCmd];
if(curCmd==60){
ReportData->LX = stickCnt;
lastLX = stickCnt;
}
if(curCmd==61){
ReportData->LY = stickCnt;
lastLY = stickCnt;
}
if(curCmd==62){
ReportData->RX = stickCnt;
lastRX = stickCnt;
}
if(curCmd==63){
ReportData->RY = stickCnt;
lastRY = stickCnt;
}
}
}
/************************** low frequent use *****************************/
// Process and deliver data from IN and OUT endpoints.
void HID_Task(void) {
// If the device isn't connected and properly configured, we can't do anything here.
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
// We'll start with the OUT endpoint.
Endpoint_SelectEndpoint(JOYSTICK_OUT_EPADDR);
// We'll check to see if we received something on the OUT endpoint.
if (Endpoint_IsOUTReceived())
{
// If we did, and the packet has data, we'll react to it.
if (Endpoint_IsReadWriteAllowed())
{
// We'll create a place to store our data received from the host.
USB_JoystickReport_Output_t JoystickOutputData;
// We'll then take in that data, setting it up in our storage.
while(Endpoint_Read_Stream_LE(&JoystickOutputData, sizeof(JoystickOutputData), NULL) != ENDPOINT_RWSTREAM_NoError);
// At this point, we can react to this data.
// However, since we're not doing anything with this data, we abandon it.
}
// Regardless of whether we reacted to the data, we acknowledge an OUT packet on this endpoint.
Endpoint_ClearOUT();
}
// We'll then move on to the IN endpoint.
Endpoint_SelectEndpoint(JOYSTICK_IN_EPADDR);
// We first check to see if the host is ready to accept data.
if (Endpoint_IsINReady())
{
// We'll create an empty report.
USB_JoystickReport_Input_t JoystickInputData;
// We'll then populate this report with what we want to send to the host.
GetNextReport(&JoystickInputData);
// Once populated, we can output this data to the host. We do this by first writing the data to the control stream.
while(Endpoint_Write_Stream_LE(&JoystickInputData, sizeof(JoystickInputData), NULL) != ENDPOINT_RWSTREAM_NoError);
// We then send an IN packet on this endpoint.
Endpoint_ClearIN();
}
}
// Fired when the host set the current configuration of the USB device after enumeration.
void EVENT_USB_Device_ConfigurationChanged(void) {
bool ConfigSuccess = true;
// We setup the HID report endpoints.
ConfigSuccess &= Endpoint_ConfigureEndpoint(JOYSTICK_OUT_EPADDR, EP_TYPE_INTERRUPT, JOYSTICK_EPSIZE, 1);
ConfigSuccess &= Endpoint_ConfigureEndpoint(JOYSTICK_IN_EPADDR, EP_TYPE_INTERRUPT, JOYSTICK_EPSIZE, 1);
// We can read ConfigSuccess to indicate a success or failure at this point.
}
/************************Useless function**************/
// Fired to indicate that the device is enumerating.
void EVENT_USB_Device_Connect(void) {
// We can indicate that we're enumerating here (via status LEDs, sound, etc.).
}
// Fired to indicate that the device is no longer connected to a host.
void EVENT_USB_Device_Disconnect(void) {
// We can indicate that our device is not ready (via status LEDs, sound, etc.).
}
// Process control requests sent to the device from the USB host.
void EVENT_USB_Device_ControlRequest(void) {
// We can handle two control requests: a Get