1/*
2 * Copyright (c) 2007-2013 ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#ifndef USB_KEYBOARD_DRIVER_H_
11#define USB_KEYBOARD_DRIVER_H_
12
13#include <usb/usb_transfer.h>
14#include <usb/class/usb_hid.h>
15
16#define USB_KEYBOARD_MODE_ATCODE 1
17
18#define USB_KEYBOARD_BUFSIZE 64
19#define USB_KEYBOARD_MODIFIIERS 8
20#define USB_KEYBOARD_KEYCODES 6
21#define USB_KEYBOARD_IN_BUFSIZE \
22    (2*(USB_KEYBOARD_MODIFIIERS + (2*USB_KEYBOARD_KEYCODES)))
23
24/// enumeration of USB keyboard transfers
25enum {
26    USB_KEYBOARD_DATA,          ///< used for data transfers to get key events
27    USB_KEYBOARD_DATA_2,
28    USB_KEYBOARD_NUM_TRANSFERS,  ///< number of transfers
29};
30
31/**
32 * this union represents the possible modifiers for the pressed key code
33 */
34union usb_keyboard_modifiers {
35    struct {
36        uint8_t ctrl_l :1;
37        uint8_t shift_l :1;
38        uint8_t alt_l :1;
39        uint8_t win_l :1;
40        uint8_t ctrl_r :1;
41        uint8_t shift_r :1;
42        uint8_t alt_r :1;
43        uint8_t win_r :1;
44        uint8_t eject :1;
45        uint8_t fn :1;
46        uint8_t slock : 1;
47        uint8_t nlock : 1;
48        uint8_t clock : 1;
49        uint8_t _unused :3;
50    };
51    uint16_t generic;
52};
53
54#define USB_KEYBOARD_MODIFIER_CHECK(_mod) \
55    if (keyboard._mod.valid && (rid == keyboard._mod.report_id)) { \
56        if (usb_hid_get_data(data, length, &(keyboard._mod.loc))) {\
57            keyboard.modifiers._mod = 1;\
58        }\
59    }\
60
61#define USB_KEYBOARD_KEY_RELEASE_CHECK(_key, _value) \
62    if (old_mod->_key != new_mod->_key) { \
63        usb_keyboard_put_key(_value | (new_mod->_key ? \
64                USB_KEYBOARD_KEY_PRESS : USB_KEYBOARD_KEY_RELEASE)); \
65    } \
66
67/**
68 *
69 */
70struct usb_keyboard_led {
71    uint8_t scrolllock :1;
72    uint8_t numlock :1;
73    uint8_t capslock :1;
74    uint8_t reserved :5;
75};
76
77/**
78 * this structure represents a pressed key event with the corresponding
79 * modifiers such as alt/shift/ctrl...
80 */
81struct usb_keyboard_data {
82    union usb_keyboard_modifiers modifiers;  ///< the activated modifiers
83    int32_t keycode[USB_KEYBOARD_KEYCODES];  ///> the raw extracted keycode (can be error)
84};
85
86
87#define USB_KEYBOARD_KEY_ERROR 0x20000000 //0x01
88#define USB_KEYBOARD_KEY_NOKEY 0x01000000 //0x0
89#define USB_KEYBOARD_KEY_PRESS 0x00
90#define USB_KEYBOARD_KEY_RELEASE 0x400
91#define USB_KEYBOARD_SCAN_RELEASE 0x80
92
93struct usb_keyboard_key {
94    struct usb_hid_location loc;
95    uint8_t report_id;
96    uint8_t valid;
97};
98
99struct usb_keyboard {
100    /* location of special keys */
101    struct usb_keyboard_key ctrl_l;
102    struct usb_keyboard_key ctrl_r;
103    struct usb_keyboard_key shift_l;
104    struct usb_keyboard_key shift_r;
105    struct usb_keyboard_key alt_l;
106    struct usb_keyboard_key alt_r;
107    struct usb_keyboard_key win_l;
108    struct usb_keyboard_key win_r;
109    struct usb_keyboard_key events;
110    struct usb_keyboard_key numlock;
111    struct usb_keyboard_key capslock;
112    struct usb_keyboard_key scrolllock;
113
114    union usb_keyboard_modifiers state;
115    union usb_keyboard_modifiers modifiers;
116    struct usb_keyboard_data new_data;
117    struct usb_keyboard_data old_data;
118
119    uint8_t num_config;  ///< the number of configurations
120    usb_xfer_id_t xferids[USB_KEYBOARD_NUM_TRANSFERS];
121    uint8_t buffer[USB_KEYBOARD_BUFSIZE];
122
123    uint32_t last_active[128];
124    uint32_t composed_char;
125    uint8_t composed_done;
126
127#if USB_KEYBOARD_MODE_ATCODE
128    uint32_t at_buffered_char[2];
129#endif
130
131    uint8_t usb_iface_number;
132
133    uint8_t keyboard_id;
134    int32_t keyboard_size;
135    uint16_t keyboard_led_size;
136    struct usb_keyboard_led keyboard_led_state;
137
138    /* input buffers */
139    uint32_t input[USB_KEYBOARD_IN_BUFSIZE];
140    uint16_t input_head;
141    uint16_t input_tail;
142    uint16_t input_size;
143};
144
145typedef struct usb_keyboard usb_keyboard_t;
146
147void usb_keyboard_deinit(void);
148usb_error_t usb_keyboard_init(void);
149usb_error_t usb_keyboard_start_transfers(void);
150
151//#define USB_DEBUG_KBD(x...) debug_printf(x)
152#define USB_DEBUG_KBD(x...)
153
154
155#endif /* USB_KEYBOARD_DRIVER_H_ */
156