add support for hid gamepad interface

add documentation for HID joystick
Add joystick_task to read analog axes values even when no key is pressed or release. update doc
Update docs/feature_joystick.md
Manage pin setup and read to maintain matrix scan after analog read
This commit is contained in:
achol 2018-10-17 11:23:20 +02:00 committed by a-chol
parent d8f3c28a37
commit 3cf7611139
15 changed files with 675 additions and 2 deletions

View file

@ -26,6 +26,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "debug.h"
#include "host_driver.h"
#include "vusb.h"
#include "joystick.h"
#include "joystick.h"
#include <util/delay.h>
static uint8_t vusb_keyboard_leds = 0;
@ -79,6 +81,7 @@ static void send_keyboard(report_keyboard_t *report);
static void send_mouse(report_mouse_t *report);
static void send_system(uint16_t data);
static void send_consumer(uint16_t data);
static void send_joystick(void);
static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
@ -139,6 +142,68 @@ static void send_consumer(uint16_t data) {
#endif
}
typedef struct {
uint8_t report_id;
#if JOYSTICK_AXES_COUNT>0
int8_t axes[JOYSTICK_AXES_COUNT];
#endif
#if JOYSTICK_BUTTON_COUNT>0
uint8_t buttons[(JOYSTICK_BUTTON_COUNT-1)/8+1];
#endif
} __attribute__ ((packed)) vusb_joystick_report_t;
void send_joystick_packet(joystick_t* status)
{
vusb_joystick_report_t r = {
.report_id = 0x4,
#if JOYSTICK_AXES_COUNT>0
.axes = {
status->axes[0]
#if JOYSTICK_AXES_COUNT >= 2
,status->axes[1]
#endif
#if JOYSTICK_AXES_COUNT >= 3
,status->axes[2]
#endif
#if JOYSTICK_AXES_COUNT >= 4
,status->axes[3]
#endif
#if JOYSTICK_AXES_COUNT >= 5
,status->axes[4]
#endif
#if JOYSTICK_AXES_COUNT >= 6
,status->axes[5]
#endif
},
#endif //JOYSTICK_AXES_COUNT>0
#if JOYSTICK_BUTTON_COUNT>0
.buttons = {
status->buttons[0]
#if JOYSTICK_BUTTON_COUNT>8
,status->buttons[1]
#endif
#if JOYSTICK_BUTTON_COUNT>16
,status->buttons[2]
#endif
#if JOYSTICK_BUTTON_COUNT>24
,status->buttons[3]
#endif
}
#endif //JOYSTICK_BUTTON_COUNT>0
};
if (usbInterruptIsReady3()) {
usbSetInterrupt3((void *)&r, sizeof(vusb_joystick_report_t));
}
}
/*------------------------------------------------------------------*
* Request from host *
*------------------------------------------------------------------*/
@ -251,7 +316,7 @@ const PROGMEM uchar keyboard_hid_report[] = {
0xC0 // End Collection
};
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) || defined(JOYSTICK_ENABLE)
const PROGMEM uchar mouse_extra_hid_report[] = {
# ifdef MOUSE_ENABLE
// Mouse report descriptor
@ -332,6 +397,47 @@ const PROGMEM uchar mouse_extra_hid_report[] = {
0x81, 0x00, // Input (Data, Array, Absolute)
0xC0 // End Collection
# endif
#if JOYSTICK_ENABLE
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x04, // USAGE (Joystick)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x4, // REPORT_ID (4)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
#if JOYSTICK_AXES_COUNT >= 1
0x09, 0x30, // USAGE (X)
#endif
#if JOYSTICK_AXES_COUNT >= 2
0x09, 0x31, // USAGE (Y)
#endif
#if JOYSTICK_AXES_COUNT >= 3
0x09, 0x32, // USAGE (Z)
#endif
#if JOYSTICK_AXES_COUNT >= 4
0x09, 0x33, // USAGE (RX)
#endif
#if JOYSTICK_AXES_COUNT >= 5
0x09, 0x34, // USAGE (RY)
#endif
#if JOYSTICK_AXES_COUNT >= 6
0x09, 0x35, // USAGE (RZ)
#endif
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, JOYSTICK_AXES_COUNT, // REPORT_COUNT (JOYSTICK_AXES_COUNT)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, JOYSTICK_BUTTON_COUNT, // USAGE_MAXIMUM
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, JOYSTICK_BUTTON_COUNT, // REPORT_COUNT
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0 // END_COLLECTION
#endif //GAMEPAD_ENABLE
};
#endif