aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/protocol/chibios/usb_main.c124
1 files changed, 69 insertions, 55 deletions
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index b90bcd037..740763de2 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -15,6 +15,16 @@
15 * GPL v2 or later. 15 * GPL v2 or later.
16 */ 16 */
17 17
18/*
19 * Implementation notes:
20 *
21 * USBEndpointConfig - Configured using explicit order instead of struct member name.
22 * This is due to ChibiOS hal LLD differences, which is dependent on hardware,
23 * "USBv1" devices have `ep_buffers` and "OTGv1" have `in_multiplier`.
24 * Given `USBv1/hal_usb_lld.h` marks the field as "not currently used" this code file
25 * makes the assumption this is safe to avoid littering with preprocessor directives.
26 */
27
18#include "ch.h" 28#include "ch.h"
19#include "hal.h" 29#include "hal.h"
20 30
@@ -98,7 +108,7 @@ static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype
98#ifndef KEYBOARD_SHARED_EP 108#ifndef KEYBOARD_SHARED_EP
99/* keyboard endpoint state structure */ 109/* keyboard endpoint state structure */
100static USBInEndpointState kbd_ep_state; 110static USBInEndpointState kbd_ep_state;
101/* keyboard endpoint initialization structure (IN) */ 111/* keyboard endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
102static const USBEndpointConfig kbd_ep_config = { 112static const USBEndpointConfig kbd_ep_config = {
103 USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ 113 USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
104 NULL, /* SETUP packet notification callback */ 114 NULL, /* SETUP packet notification callback */
@@ -117,7 +127,7 @@ static const USBEndpointConfig kbd_ep_config = {
117/* mouse endpoint state structure */ 127/* mouse endpoint state structure */
118static USBInEndpointState mouse_ep_state; 128static USBInEndpointState mouse_ep_state;
119 129
120/* mouse endpoint initialization structure (IN) */ 130/* mouse endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
121static const USBEndpointConfig mouse_ep_config = { 131static const USBEndpointConfig mouse_ep_config = {
122 USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ 132 USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
123 NULL, /* SETUP packet notification callback */ 133 NULL, /* SETUP packet notification callback */
@@ -136,7 +146,7 @@ static const USBEndpointConfig mouse_ep_config = {
136/* shared endpoint state structure */ 146/* shared endpoint state structure */
137static USBInEndpointState shared_ep_state; 147static USBInEndpointState shared_ep_state;
138 148
139/* shared endpoint initialization structure (IN) */ 149/* shared endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
140static const USBEndpointConfig shared_ep_config = { 150static const USBEndpointConfig shared_ep_config = {
141 USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ 151 USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
142 NULL, /* SETUP packet notification callback */ 152 NULL, /* SETUP packet notification callback */
@@ -164,58 +174,62 @@ typedef struct {
164 QMKUSBDriver driver; 174 QMKUSBDriver driver;
165} usb_driver_config_t; 175} usb_driver_config_t;
166 176
167#define QMK_USB_DRIVER_CONFIG(stream, notification, fixedsize) \ 177/* Reusable initialization structure - see USBEndpointConfig comment at top of file */
168 { \ 178#define QMK_USB_DRIVER_CONFIG(stream, notification, fixedsize) \
169 .queue_capacity_in = stream##_IN_CAPACITY, .queue_capacity_out = stream##_OUT_CAPACITY, \ 179 { \
170 .in_ep_config = {.ep_mode = stream##_IN_MODE, \ 180 .queue_capacity_in = stream##_IN_CAPACITY, .queue_capacity_out = stream##_OUT_CAPACITY, \
171 .setup_cb = NULL, \ 181 .in_ep_config = \
172 .in_cb = qmkusbDataTransmitted, \ 182 { \
173 .out_cb = NULL, \ 183 stream##_IN_MODE, /* Interrupt EP */ \
174 .in_maxsize = stream##_EPSIZE, \ 184 NULL, /* SETUP packet notification callback */ \
175 .out_maxsize = 0, /* The pointer to the states will be filled during initialization */ \ 185 qmkusbDataTransmitted, /* IN notification callback */ \
176 .in_state = NULL, \ 186 NULL, /* OUT notification callback */ \
177 .out_state = NULL, \ 187 stream##_EPSIZE, /* IN maximum packet size */ \
178 .ep_buffers = 2, \ 188 0, /* OUT maximum packet size */ \
179 .setup_buf = NULL}, \ 189 NULL, /* IN Endpoint state */ \
180 .out_ep_config = \ 190 NULL, /* OUT endpoint state */ \
181 { \ 191 2, /* IN multiplier */ \
182 .ep_mode = stream##_OUT_MODE, \ 192 NULL /* SETUP buffer (not a SETUP endpoint) */ \
183 .setup_cb = NULL, \ 193 }, \
184 .in_cb = NULL, \ 194 .out_ep_config = \
185 .out_cb = qmkusbDataReceived, \ 195 { \
186 .in_maxsize = 0, \ 196 stream##_OUT_MODE, /* Interrupt EP */ \
187 .out_maxsize = stream##_EPSIZE, /* The pointer to the states will be filled during initialization */ \ 197 NULL, /* SETUP packet notification callback */ \
188 .in_state = NULL, \ 198 NULL, /* IN notification callback */ \
189 .out_state = NULL, \ 199 qmkusbDataReceived, /* OUT notification callback */ \
190 .ep_buffers = 2, \ 200 0, /* IN maximum packet size */ \
191 .setup_buf = NULL, \ 201 stream##_EPSIZE, /* OUT maximum packet size */ \
192 }, \ 202 NULL, /* IN Endpoint state */ \
193 .int_ep_config = \ 203 NULL, /* OUT endpoint state */ \
194 { \ 204 2, /* IN multiplier */ \
195 .ep_mode = USB_EP_MODE_TYPE_INTR, \ 205 NULL, /* SETUP buffer (not a SETUP endpoint) */ \
196 .setup_cb = NULL, \ 206 }, \
197 .in_cb = qmkusbInterruptTransmitted, \ 207 .int_ep_config = \
198 .out_cb = NULL, \ 208 { \
199 .in_maxsize = CDC_NOTIFICATION_EPSIZE, \ 209 USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ \
200 .out_maxsize = 0, /* The pointer to the states will be filled during initialization */ \ 210 NULL, /* SETUP packet notification callback */ \
201 .in_state = NULL, \ 211 qmkusbInterruptTransmitted, /* IN notification callback */ \
202 .out_state = NULL, \ 212 NULL, /* OUT notification callback */ \
203 .ep_buffers = 2, \ 213 CDC_NOTIFICATION_EPSIZE, /* IN maximum packet size */ \
204 .setup_buf = NULL, \ 214 0, /* OUT maximum packet size */ \
205 }, \ 215 NULL, /* IN Endpoint state */ \
206 .config = { \ 216 NULL, /* OUT endpoint state */ \
207 .usbp = &USB_DRIVER, \ 217 2, /* IN multiplier */ \
208 .bulk_in = stream##_IN_EPNUM, \ 218 NULL, /* SETUP buffer (not a SETUP endpoint) */ \
209 .bulk_out = stream##_OUT_EPNUM, \ 219 }, \
210 .int_in = notification, \ 220 .config = { \
211 .in_buffers = stream##_IN_CAPACITY, \ 221 .usbp = &USB_DRIVER, \
212 .out_buffers = stream##_OUT_CAPACITY, \ 222 .bulk_in = stream##_IN_EPNUM, \
213 .in_size = stream##_EPSIZE, \ 223 .bulk_out = stream##_OUT_EPNUM, \
214 .out_size = stream##_EPSIZE, \ 224 .int_in = notification, \
215 .fixed_size = fixedsize, \ 225 .in_buffers = stream##_IN_CAPACITY, \
216 .ib = (uint8_t[BQ_BUFFER_SIZE(stream##_IN_CAPACITY, stream##_EPSIZE)]){}, \ 226 .out_buffers = stream##_OUT_CAPACITY, \
217 .ob = (uint8_t[BQ_BUFFER_SIZE(stream##_OUT_CAPACITY, stream##_EPSIZE)]){}, \ 227 .in_size = stream##_EPSIZE, \
218 } \ 228 .out_size = stream##_EPSIZE, \
229 .fixed_size = fixedsize, \
230 .ib = (uint8_t[BQ_BUFFER_SIZE(stream##_IN_CAPACITY, stream##_EPSIZE)]){}, \
231 .ob = (uint8_t[BQ_BUFFER_SIZE(stream##_OUT_CAPACITY, stream##_EPSIZE)]){}, \
232 } \
219 } 233 }
220 234
221typedef struct { 235typedef struct {