#ifndef _CORE_KEYPAD_H_
#define _CORE_KEYPAD_H_

#include <core/types.h>

/****************************************************************************************************************
 *
 * Keypad matrix configuration.
 *
 * The matrix can consist of up to 16 rows and 16 columns, but no more than 127 keys total.
 *
 * The rows are used as outputs, while the columns are inputs.
 *
 *        Characters printed
 *        on standard keypad                      Key numbering
 *
 *        CL0 CL1 CL2 CL3                         CL0 CL1 CL2 CL3 
 *       +---+---+---+---+		         +---+---+---+---+
 *  ROW0 | 1 | 4 | 7 | A |		    ROW0 | 1 | 2 | 3 | 4 |
 *       +---+---+---+---+		         +---+---+---+---+
 *  ROW1 | 2 | 5 | 8 | 0 |		    ROW1 | 5 | 6 | 7 | 8 |
 *       +---+---+---+---+		         +---+---+---+---+
 *  ROW2 | 3 | 6 | 9 | B |		    ROW2 | 9 |10 |11 |12 |
 *       +---+---+---+---+		         +---+---+---+---+
 *  ROW3 | F | E | D | C |		    ROW3 |13 |14 |15 |16 |
 *       +---+---+---+---+		         +---+---+---+---+
 *
 * Events are reported using the USB HID "Button" Usage Page (0x09)
 * As USB defines 0 as "no button", we start numbering at 1.
 *
 * Board dependency:
 *
 * V4r3: The default mapping is a 4x4 keypad on IN0..IN3 vs. LED0...LED3.
 *         ROW0 = LED3 ... ROW3 = LED0
 *         COL0 = IN3  ... COL3 = IN0
 *       Actual pins used for ROW/COL can be configured freely from the choices
 *       of available sidekick GPIOs. Any unused ROW/COL must be set to 0xFF.
 *
 * V4.5p1: There is a dedicated keypad port with pins labelled ROWx/COLx already.
 *
 */
struct keypad_matrix {
  uint8 rows[16];
  uint8 cols[16];
};

#define KEYPAD_SETMATRIX	0x4B00
#define KEYPAD_GETMATRIX	0x4B01

/****************************************************************************************************************
 *
 * Rotary encoder configuration
 *
 * Up to five rotary encoders may be configured on V4r3, each encoder needs two input pins.
 *
 * Events are reported using wheel input events.
 *
 */
#define KEYPAD_WHEEL_ONE_EDGE		0		/* Encoder reports one edges per 'click'		*/
#define KEYPAD_WHEEL_TWO_EDGES		1		/* Encoder reports two edges per 'click'		*/
#define KEYPAD_WHEEL_FOUR_EDGES		3		/* Encoder reports four edges per 'click'		*/

struct keypad_wheel {
  uint wheel;		// Wheel number to configure
  uint group;		// gpio pin group
  uint pin1;		// First pin of quadrature signal
  uint pin2;		// Second pin of quadrature signal
  uint flags;		// Special flags
  uint scancode1;	// Scancode for forward direction
  uint scancode2;	// Scancode for reverse direction
};

#define KEYPAD_SETWHEEL		0x4B06
#define KEYPAD_GETWHEEL		0x4B07

/****************************************************************************************************************
 *
 * Button configuration
 *
 * Up to sixteen generic buttons can be configured.
 *
 */
struct keypad_button {
  uint button;		// Button number to configure
  uint group;		// gpio pin group
  uint pin;		// Pin used for button
  uint scancode;	// Scancode for button
};

#define KEYPAD_SETBUTTON	0x4B08
#define KEYPAD_GETBUTTON	0x4B09

/****************************************************************************************************************
 *
 * Deprecated, to keep old binaries
 *
 */
struct keypad_wheel_v1 {
  uint wheel;		// Wheel number to configure
  uint pin1;		// First pin of quadrature signal
  uint pin2;		// Second pin of quadrature signal
  uint flags;		// Special flags
  uint scancode1;	// Scancode for forward direction
  uint scancode2;	// Scancode for reverse direction
};

#define KEYPAD_SETWHEEL_V1	0x4B02
#define KEYPAD_GETWHEEL_V1	0x4B03

struct keypad_button_v1 {
  uint button;		// Button number to configure
  uint pin;		// Pin used for button
  uint scancode;	// Scancode for button
};

#define KEYPAD_SETBUTTON_V1	0x4B04
#define KEYPAD_GETBUTTON_V1	0x4B05

/****************************************************************************************************************/
#endif
