4 Copyright (c) 2016 Fred Sundvik
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 #include "host_driver.h"
26 #include "serial_link/system/serial_link.h"
28 #include "serial_link/protocol/byte_stuffer.h"
29 #include "serial_link/protocol/transport.h"
30 #include "serial_link/protocol/frame_router.h"
36 static event_source_t new_data_event;
37 static bool serial_link_connected;
38 static bool is_master = false;
40 static uint8_t keyboard_leds(void);
41 static void send_keyboard(report_keyboard_t *report);
42 static void send_mouse(report_mouse_t *report);
43 static void send_system(uint16_t data);
44 static void send_consumer(uint16_t data);
46 host_driver_t serial_driver = {
54 // Define these in your Config.h file
55 #ifndef SERIAL_LINK_BAUD
56 #error "Serial link baud is not set"
59 #ifndef SERIAL_LINK_THREAD_PRIORITY
60 #error "Serial link thread priority not set"
63 static SerialConfig config = {
64 .sc_speed = SERIAL_LINK_BAUD
67 //#define DEBUG_LINK_ERRORS
69 static uint32_t read_from_serial(SerialDriver* driver, uint8_t link) {
70 const uint32_t buffer_size = 16;
71 uint8_t buffer[buffer_size];
72 uint32_t bytes_read = sdAsynchronousRead(driver, buffer, buffer_size);
73 uint8_t* current = buffer;
74 uint8_t* end = current + bytes_read;
75 while(current < end) {
76 byte_stuffer_recv_byte(link, *current);
82 static void print_error(char* str, eventflags_t flags, SerialDriver* driver) {
83 #ifdef DEBUG_LINK_ERRORS
84 if (flags & SD_PARITY_ERROR) {
86 print(" Parity error\n");
88 if (flags & SD_FRAMING_ERROR) {
90 print(" Framing error\n");
92 if (flags & SD_OVERRUN_ERROR) {
94 uint32_t size = qSpaceI(&(driver->iqueue));
95 xprintf(" Overrun error, queue size %d\n", size);
98 if (flags & SD_NOISE_ERROR) {
100 print(" Noise error\n");
102 if (flags & SD_BREAK_DETECTED) {
104 print(" Break detected\n");
113 bool is_serial_link_master(void) {
117 // TODO: Optimize the stack size, this is probably way too big
118 static THD_WORKING_AREA(serialThreadStack, 1024);
119 static THD_FUNCTION(serialThread, arg) {
121 event_listener_t new_data_listener;
122 event_listener_t sd1_listener;
123 event_listener_t sd2_listener;
124 chEvtRegister(&new_data_event, &new_data_listener, 0);
125 eventflags_t events = CHN_INPUT_AVAILABLE
126 | SD_PARITY_ERROR | SD_FRAMING_ERROR | SD_OVERRUN_ERROR | SD_NOISE_ERROR | SD_BREAK_DETECTED;
127 chEvtRegisterMaskWithFlags(chnGetEventSource(&SD1),
131 chEvtRegisterMaskWithFlags(chnGetEventSource(&SD2),
135 bool need_wait = false;
137 eventflags_t flags1 = 0;
138 eventflags_t flags2 = 0;
140 eventmask_t mask = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(1000));
141 if (mask & EVENT_MASK(1)) {
142 flags1 = chEvtGetAndClearFlags(&sd1_listener);
143 print_error("DOWNLINK", flags1, &SD1);
145 if (mask & EVENT_MASK(2)) {
146 flags2 = chEvtGetAndClearFlags(&sd2_listener);
147 print_error("UPLINK", flags2, &SD2);
151 // Always stay as master, even if the USB goes into sleep mode
152 is_master |= usbGetDriverStateI(&USBD1) == USB_ACTIVE;
153 router_set_master(is_master);
156 need_wait &= read_from_serial(&SD2, UP_LINK) == 0;
157 need_wait &= read_from_serial(&SD1, DOWN_LINK) == 0;
162 void send_data(uint8_t link, const uint8_t* data, uint16_t size) {
163 if (link == DOWN_LINK) {
164 sdWrite(&SD1, data, size);
167 sdWrite(&SD2, data, size);
171 static systime_t last_update = 0;
174 matrix_row_t rows[MATRIX_ROWS];
177 static matrix_object_t last_matrix = {};
179 SLAVE_TO_MASTER_OBJECT(keyboard_matrix, matrix_object_t);
180 MASTER_TO_ALL_SLAVES_OBJECT(serial_link_connected, bool);
182 static remote_object_t* remote_objects[] = {
183 REMOTE_OBJECT(serial_link_connected),
184 REMOTE_OBJECT(keyboard_matrix),
187 void init_serial_link(void) {
188 serial_link_connected = false;
189 init_serial_link_hal();
190 add_remote_objects(remote_objects, sizeof(remote_objects)/sizeof(remote_object_t*));
192 sdStart(&SD1, &config);
193 sdStart(&SD2, &config);
194 chEvtObjectInit(&new_data_event);
195 (void)chThdCreateStatic(serialThreadStack, sizeof(serialThreadStack),
196 SERIAL_LINK_THREAD_PRIORITY, serialThread, NULL);
199 void matrix_set_remote(matrix_row_t* rows, uint8_t index);
201 void serial_link_update(void) {
202 if (read_serial_link_connected()) {
203 serial_link_connected = true;
206 matrix_object_t matrix;
207 bool changed = false;
208 for(uint8_t i=0;i<MATRIX_ROWS;i++) {
209 matrix.rows[i] = matrix_get_row(i);
210 changed |= matrix.rows[i] != last_matrix.rows[i];
213 systime_t current_time = chVTGetSystemTimeX();
214 systime_t delta = current_time - last_update;
215 if (changed || delta > US2ST(5000)) {
216 last_update = current_time;
217 last_matrix = matrix;
218 matrix_object_t* m = begin_write_keyboard_matrix();
219 for(uint8_t i=0;i<MATRIX_ROWS;i++) {
220 m->rows[i] = matrix.rows[i];
222 end_write_keyboard_matrix();
223 *begin_write_serial_link_connected() = true;
224 end_write_serial_link_connected();
227 matrix_object_t* m = read_keyboard_matrix(0);
229 matrix_set_remote(m->rows, 0);
233 void signal_data_written(void) {
234 chEvtBroadcast(&new_data_event);
237 bool is_serial_link_connected(void) {
238 return serial_link_connected;
241 host_driver_t* get_serial_link_driver(void) {
242 return &serial_driver;
245 // NOTE: The driver does nothing, because the master handles everything
246 uint8_t keyboard_leds(void) {
250 void send_keyboard(report_keyboard_t *report) {
254 void send_mouse(report_mouse_t *report) {
258 void send_system(uint16_t data) {
262 void send_consumer(uint16_t data) {