Parent directory

joystick.h

3988 bytes
  1/* Copyright 2022
  2 *
  3 * This program is free software: you can redistribute it and/or modify
  4 * it under the terms of the GNU General Public License as published by
  5 * the Free Software Foundation, either version 2 of the License, or
  6 * (at your option) any later version.
  7 *
  8 * This program is distributed in the hope that it will be useful,
  9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11 * GNU General Public License for more details.
 12 *
 13 * You should have received a copy of the GNU General Public License
 14 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 15 */
 16
 17#pragma once
 18
 19#include <stdbool.h>
 20#include <stdint.h>
 21
 22#include "gpio.h"
 23
 24/**
 25 * \file
 26 *
 27 * \defgroup joystick HID Joystick
 28 * \{
 29 */
 30
 31#ifndef JOYSTICK_BUTTON_COUNT
 32#    define JOYSTICK_BUTTON_COUNT 8
 33#elif JOYSTICK_BUTTON_COUNT > 32
 34#    error Joystick feature only supports up to 32 buttons
 35#endif
 36
 37#ifndef JOYSTICK_AXIS_COUNT
 38#    define JOYSTICK_AXIS_COUNT 2
 39#elif JOYSTICK_AXIS_COUNT > 6
 40#    error Joystick feature only supports up to 6 axes
 41#endif
 42
 43#if JOYSTICK_AXIS_COUNT == 0 && JOYSTICK_BUTTON_COUNT == 0
 44#    error Joystick feature requires at least one axis or button
 45#endif
 46
 47#ifndef JOYSTICK_AXIS_RESOLUTION
 48#    define JOYSTICK_AXIS_RESOLUTION 8
 49#elif JOYSTICK_AXIS_RESOLUTION < 8 || JOYSTICK_AXIS_RESOLUTION > 16
 50#    error JOYSTICK_AXIS_RESOLUTION must be between 8 and 16
 51#endif
 52
 53#define JOYSTICK_MAX_VALUE ((1L << (JOYSTICK_AXIS_RESOLUTION - 1)) - 1)
 54
 55#define JOYSTICK_HAT_CENTER -1
 56#define JOYSTICK_HAT_NORTH 0
 57#define JOYSTICK_HAT_NORTHEAST 1
 58#define JOYSTICK_HAT_EAST 2
 59#define JOYSTICK_HAT_SOUTHEAST 3
 60#define JOYSTICK_HAT_SOUTH 4
 61#define JOYSTICK_HAT_SOUTHWEST 5
 62#define JOYSTICK_HAT_WEST 6
 63#define JOYSTICK_HAT_NORTHWEST 7
 64
 65// configure on input_pin of the joystick_axes array entry to NO_PIN
 66// to prevent it from being read from the ADC. This allows outputting forged axis value.
 67#define JOYSTICK_AXIS_VIRTUAL \
 68    { NO_PIN, 0, JOYSTICK_MAX_VALUE / 2, JOYSTICK_MAX_VALUE }
 69#define JOYSTICK_AXIS_IN(INPUT_PIN, LOW, REST, HIGH) \
 70    { INPUT_PIN, LOW, REST, HIGH }
 71
 72typedef struct {
 73    pin_t input_pin;
 74
 75    // the AVR ADC offers 10 bit precision, with significant bits on the higher part
 76    uint16_t min_digit;
 77    uint16_t mid_digit;
 78    uint16_t max_digit;
 79} joystick_config_t;
 80
 81extern joystick_config_t joystick_axes[JOYSTICK_AXIS_COUNT];
 82
 83typedef struct {
 84    uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1];
 85    int16_t axes[JOYSTICK_AXIS_COUNT];
 86#ifdef JOYSTICK_HAS_HAT
 87    int8_t hat;
 88#endif
 89    bool dirty;
 90} joystick_t;
 91
 92extern joystick_t joystick_state;
 93
 94/**
 95 * \brief Handle the initialization of the subsystem.
 96 */
 97void joystick_init(void);
 98
 99/**
100 * \brief Handle various subsystem background tasks.
101 */
102void joystick_task(void);
103
104/**
105 * \brief Send the joystick report to the host, if it has been marked as dirty.
106 */
107void joystick_flush(void);
108
109/**
110 * \brief Set the state of a button, and flush the report.
111 *
112 * \param button The index of the button to press, from 0 to 31.
113 */
114void register_joystick_button(uint8_t button);
115
116/**
117 * \brief Reset the state of a button, and flush the report.
118 *
119 * \param button The index of the button to release, from 0 to 31.
120 */
121void unregister_joystick_button(uint8_t button);
122
123/**
124 * \brief Sample and process the analog value of the given axis.
125 *
126 * \param axis The axis to read.
127 *
128 * \return A signed 16-bit integer, where 0 is the resting or mid point.
129 */
130int16_t joystick_read_axis(uint8_t axis);
131
132/**
133 * \brief Sample and process the all axis.
134 */
135void joystick_read_axes(void);
136
137/**
138 * \brief Set the value of the given axis.
139 *
140 * \param axis The axis to set the value of.
141 * \param value The value to set.
142 */
143void joystick_set_axis(uint8_t axis, int16_t value);
144
145/**
146 * \brief Set the position of the hat switch.
147 *
148 * \param value The hat switch position to set.
149 */
150void joystick_set_hat(int8_t value);
151
152/** \} */