summaryrefslogtreecommitdiff
path: root/tmk_core/protocol
diff options
context:
space:
mode:
authorDrashna Jael're <drashna@live.com>2021-06-29 12:23:03 -0700
committerDrashna Jael're <drashna@live.com>2021-06-29 12:24:07 -0700
commitacf2c323e2927f6007b17ded577cf49fd86fec6c (patch)
tree8334dc5c71e6ab9bf33c76143eac7bb0e60159b0 /tmk_core/protocol
parentec7a7beeed3046e9144d4c4ce0ef3b2c4f9e4341 (diff)
parentf55e39e8a2246f6f96fd5d4a84a866e2615cde7b (diff)
Merge upstream QMK Firmware at '0.12.52~1'
Diffstat (limited to 'tmk_core/protocol')
-rw-r--r--tmk_core/protocol/adb.c256
-rw-r--r--tmk_core/protocol/adb.h58
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.c3
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.h4
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.c6
-rw-r--r--tmk_core/protocol/arm_atsam/md_rgb_matrix.c94
-rw-r--r--tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c8
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c42
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h7
-rw-r--r--tmk_core/protocol/chibios/main.c3
-rw-r--r--tmk_core/protocol/chibios/usb_main.c117
-rw-r--r--tmk_core/protocol/chibios/usb_main.h11
-rw-r--r--tmk_core/protocol/lufa/lufa.c35
-rw-r--r--tmk_core/protocol/lufa/outputselect.h14
-rw-r--r--tmk_core/protocol/m0110.c8
-rw-r--r--tmk_core/protocol/midi/qmk_midi.c2
-rw-r--r--tmk_core/protocol/ps2_mouse.c2
-rw-r--r--tmk_core/protocol/serial.h2
-rw-r--r--tmk_core/protocol/serial_uart.c25
-rw-r--r--tmk_core/protocol/usb_descriptor.c17
-rw-r--r--tmk_core/protocol/usb_descriptor.h3
-rw-r--r--tmk_core/protocol/usb_hid/test/Makefile126
-rw-r--r--tmk_core/protocol/usb_hid/test/config.h30
-rw-r--r--tmk_core/protocol/usb_hid/test/test.cpp92
-rw-r--r--tmk_core/protocol/vusb/main.c66
-rw-r--r--tmk_core/protocol/vusb/usbconfig.h356
-rw-r--r--tmk_core/protocol/vusb/vusb.c22
-rw-r--r--tmk_core/protocol/vusb/vusb.h3
-rw-r--r--tmk_core/protocol/xt.h41
-rw-r--r--tmk_core/protocol/xt_interrupt.c13
30 files changed, 915 insertions, 551 deletions
diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c
index a23c919619..367f1b09fa 100644
--- a/tmk_core/protocol/adb.c
+++ b/tmk_core/protocol/adb.c
@@ -1,5 +1,5 @@
/*
-Copyright 2011 Jun WAKO <wakojun@gmail.com>
+Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
Copyright 2013 Shay Green <gblargg@gmail.com>
This software is licensed with a Modified BSD License.
@@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <avr/io.h>
#include <avr/interrupt.h>
#include "adb.h"
+#include "print.h"
// GCC doesn't inline functions normally
#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT))
@@ -59,7 +60,6 @@ static inline void place_bit1(void);
static inline void send_byte(uint8_t data);
static inline uint16_t wait_data_lo(uint16_t us);
static inline uint16_t wait_data_hi(uint16_t us);
-static inline uint16_t adb_host_dev_recv(uint8_t device);
void adb_host_init(void) {
ADB_PORT &= ~(1 << ADB_DATA_BIT);
@@ -81,119 +81,164 @@ bool adb_host_psw(void) { return psw_in(); }
* <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
* <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
*/
-
-// ADB Bit Cells
-//
-// bit cell time: 70-130us
-// low part of bit0: 60-70% of bit cell
-// low part of bit1: 30-40% of bit cell
-//
-// bit cell time 70us 130us
-// --------------------------------------------
-// low part of bit0 42-49 78-91
-// high part of bit0 21-28 39-52
-// low part of bit1 21-28 39-52
-// high part of bit1 42-49 78-91
-//
-//
-// bit0:
-// 70us bit cell:
-// ____________~~~~~~
-// 42-49 21-28
-//
-// 130us bit cell:
-// ____________~~~~~~
-// 78-91 39-52
-//
-// bit1:
-// 70us bit cell:
-// ______~~~~~~~~~~~~
-// 21-28 42-49
-//
-// 130us bit cell:
-// ______~~~~~~~~~~~~
-// 39-52 78-91
-//
-// [from Apple IIgs Hardware Reference Second Edition]
-
-enum { ADDR_KEYB = 0x20, ADDR_MOUSE = 0x30 };
-
-uint16_t adb_host_kbd_recv(void) { return adb_host_dev_recv(ADDR_KEYB); }
+uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); }
#ifdef ADB_MOUSE_ENABLE
-void adb_mouse_init(void) { return; }
+__attribute__((weak)) void adb_mouse_init(void) { return; }
+
+__attribute__((weak)) void adb_mouse_task(void) { return; }
-uint16_t adb_host_mouse_recv(void) { return adb_host_dev_recv(ADDR_MOUSE); }
+uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); }
#endif
-static inline uint16_t adb_host_dev_recv(uint8_t device) {
- uint16_t data = 0;
+// This sends Talk command to read data from register and returns length of the data.
+uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
+ for (int8_t i = 0; i < len; i++) buf[i] = 0;
+
cli();
attention();
- send_byte(device | 0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00)
- place_bit0(); // Stopbit(0)
+ send_byte((addr << 4) | ADB_CMD_TALK | reg);
+ place_bit0(); // Stopbit(0)
+ // TODO: Service Request(Srq):
+ // Device holds low part of comannd stopbit for 140-260us
+ //
+ // Command:
+ // ......._ ______________________ ___ ............_ -------
+ // | | | | | | |
+ // Command | | | | | Data bytes | |
+ // ........|___| | 140-260 |__| |_............|___|
+ // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
+ //
+ // Command without data:
+ // ......._ __________________________
+ // | |
+ // Command | |
+ // ........|___| | 140-260 |
+ // |stop0 | Tlt Stop-to-Start |
+ //
+ // Service Request:
+ // ......._ ______ ___ ............_ -------
+ // | 140-260 | | | | | |
+ // Command | Service Request | | | | Data bytes | |
+ // ........|___________________| |__| |_............|___|
+ // |stop0 | |start1| |stop0 |
+ // ......._ __________
+ // | 140-260 |
+ // Command | Service Request |
+ // ........|___________________|
+ // |stop0 |
+ // This can be happened?
+ // ......._ ______________________ ___ ............_ -----
+ // | | | | | | 140-260 |
+ // Command | | | | | Data bytes | Service Request |
+ // ........|___| | 140-260 |__| |_............|_________________|
+ // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
+ //
+ // "Service requests are issued by the devices during a very specific time at the
+ // end of the reception of the command packet.
+ // If a device in need of service issues a service request, it must do so within
+ // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs."
+ //
+ // "A device sends a Service Request signal by holding the bus low during the low
+ // portion of the stop bit of any command or data transaction. The device must lengthen
+ // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15."
+ // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
+ xprintf("R");
sei();
- return -30; // something wrong
+ return 0;
}
if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
sei();
- return 0; // No data to send
+ return 0; // No data from device(not error);
+ }
+
+ // start bit(1)
+ if (!wait_data_hi(40)) {
+ xprintf("S");
+ sei();
+ return 0;
+ }
+ if (!wait_data_lo(100)) {
+ xprintf("s");
+ sei();
+ return 0;
}
- uint8_t n = 17; // start bit + 16 data bits
+ uint8_t n = 0; // bit count
do {
+ //
+ // |<- bit_cell_max(130) ->|
+ // | |<- lo ->|
+ // | | |<-hi->|
+ // _______
+ // | | |
+ // | 130-lo | lo-hi |
+ // |________| |
+ //
uint8_t lo = (uint8_t)wait_data_hi(130);
- if (!lo) goto error;
+ if (!lo) goto error; // no more bit or after stop bit
uint8_t hi = (uint8_t)wait_data_lo(lo);
- if (!hi) goto error;
+ if (!hi) goto error; // stop bit extedned by Srq?
- hi = lo - hi;
- lo = 130 - lo;
+ if (n / 8 >= len) continue; // can't store in buf
- data <<= 1;
- if (lo < hi) {
- data |= 1;
- } else if (n == 17) {
- sei();
- return -20;
+ buf[n / 8] <<= 1;
+ if ((130 - lo) < (lo - hi)) {
+ buf[n / 8] |= 1;
}
- } while (--n);
-
- // Stop bit can't be checked normally since it could have service request lenghtening
- // and its high state never goes low.
- if (!wait_data_hi(351) || wait_data_lo(91)) {
- sei();
- return -21;
- }
- sei();
- return data;
+ } while (++n);
error:
sei();
- return -n;
+ return n / 8;
}
-void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) {
+uint16_t adb_host_talk(uint8_t addr, uint8_t reg) {
+ uint8_t len;
+ uint8_t buf[8];
+ len = adb_host_talk_buf(addr, reg, buf, 8);
+ if (len != 2) return 0;
+ return (buf[0] << 8 | buf[1]);
+}
+
+void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
cli();
attention();
- send_byte(cmd);
- place_bit0(); // Stopbit(0)
+ send_byte((addr << 4) | ADB_CMD_LISTEN | reg);
+ place_bit0(); // Stopbit(0)
+ // TODO: Service Request
_delay_us(200); // Tlt/Stop to Start
place_bit1(); // Startbit(1)
- send_byte(data_h);
- send_byte(data_l);
+ for (int8_t i = 0; i < len; i++) {
+ send_byte(buf[i]);
+ // xprintf("%02X ", buf[i]);
+ }
place_bit0(); // Stopbit(0);
sei();
}
+void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) {
+ uint8_t buf[2] = {data_h, data_l};
+ adb_host_listen_buf(addr, reg, buf, 2);
+}
+
+void adb_host_flush(uint8_t addr) {
+ cli();
+ attention();
+ send_byte((addr << 4) | ADB_CMD_FLUSH);
+ place_bit0(); // Stopbit(0)
+ _delay_us(200); // Tlt/Stop to Start
+ sei();
+}
+
// send state of LEDs
void adb_host_kbd_led(uint8_t led) {
- // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10)
- // send upper byte (not used)
- // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0:
- adb_host_listen(0x2A, 0, led & 0x07);
+ // Listen Register2
+ // upper byte: not used
+ // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock
+ adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07);
}
#ifdef ADB_PSW_BIT
@@ -327,7 +372,7 @@ Commands
bits commands
------------------------------------------------------
- - - - - 0 0 0 0 Send Request(reset all devices)
+ - - - - 0 0 0 0 Send Reset(reset all devices)
A A A A 0 0 0 1 Flush(reset a device)
- - - - 0 0 1 0 Reserved
- - - - 0 0 1 1 Reserved
@@ -435,5 +480,56 @@ Keyboard LEDs & state of keys(Register2)
| +----------------------------- Delete
+------------------------------- Reserved
+Address, Handler ID and bits(Register3)
+ 1514131211 . . 8 7 . . . . . . 0
+ | | | | | | | | | | | | | | | |
+ | | | | | | | | +-+-+-+-+-+-+-+- Handler ID
+ | | | | +-+-+-+----------------- Address
+ | | | +------------------------- 0
+ | | +--------------------------- Service request enable(1 = enabled)
+ | +----------------------------- Exceptional event(alwyas 1 if not used)
+ +------------------------------- 0
+
+ADB Bit Cells
+ bit cell time: 70-130us
+ low part of bit0: 60-70% of bit cell
+ low part of bit1: 30-40% of bit cell
+
+ bit cell time 70us 130us
+ --------------------------------------------
+ low part of bit0 42-49 78-91
+ high part of bit0 21-28 39-52
+ low part of bit1 21-28 39-52
+ high part of bit1 42-49 78-91
+
+
+ bit0:
+ 70us bit cell:
+ ____________~~~~~~
+ 42-49 21-28
+
+ 130us bit cell:
+ ____________~~~~~~
+ 78-91 39-52
+
+ bit1:
+ 70us bit cell:
+ ______~~~~~~~~~~~~
+ 21-28 42-49
+
+ 130us bit cell:
+ ______~~~~~~~~~~~~
+ 39-52 78-91
+
+ [from Apple IIgs Hardware Reference Second Edition]
+
+Keyboard Handle ID
+ Apple Standard Keyboard M0116: 0x01
+ Apple Extended Keyboard M0115: 0x02
+ Apple Extended Keyboard II M3501: 0x02
+ Apple Adjustable Keybaord: 0x10
+
+ http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802
+
END_OF_ADB
*/
diff --git a/tmk_core/protocol/adb.h b/tmk_core/protocol/adb.h
index 34cbcf7691..fe8becc2d5 100644
--- a/tmk_core/protocol/adb.h
+++ b/tmk_core/protocol/adb.h
@@ -1,5 +1,5 @@
/*
-Copyright 2011 Jun WAKO <wakojun@gmail.com>
+Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
This software is licensed with a Modified BSD License.
All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -47,12 +47,60 @@ POSSIBILITY OF SUCH DAMAGE.
#define ADB_POWER 0x7F
#define ADB_CAPS 0x39
+/* ADB commands */
+// Default Address
+#define ADB_ADDR_0 0
+#define ADB_ADDR_DONGLE 1
+#define ADB_ADDR_KEYBOARD 2
+#define ADB_ADDR_MOUSE 3
+#define ADB_ADDR_TABLET 4
+#define ADB_ADDR_APPLIANCE 7
+#define ADB_ADDR_8 8
+#define ADB_ADDR_9 9
+#define ADB_ADDR_10 10
+#define ADB_ADDR_11 11
+#define ADB_ADDR_12 12
+#define ADB_ADDR_13 13
+#define ADB_ADDR_14 14
+#define ADB_ADDR_15 15
+// for temporary purpose, do not use for polling
+#define ADB_ADDR_TMP 15
+#define ADB_ADDR_MOUSE_POLL 10
+// Command Type
+#define ADB_CMD_RESET 0
+#define ADB_CMD_FLUSH 1
+#define ADB_CMD_LISTEN 8
+#define ADB_CMD_TALK 12
+// Register
+#define ADB_REG_0 0
+#define ADB_REG_1 1
+#define ADB_REG_2 2
+#define ADB_REG_3 3
+
+/* ADB keyboard handler id */
+#define ADB_HANDLER_STD 0x01 /* IIGS, M0116 */
+#define ADB_HANDLER_AEK 0x02 /* M0115, M3501 */
+#define ADB_HANDLER_AEK_RMOD 0x03 /* M0115, M3501, alternate mode enableing right modifiers */
+#define ADB_HANDLER_STD_ISO 0x04 /* M0118, ISO swapping keys */
+#define ADB_HANDLER_AEK_ISO 0x05 /* M0115, M3501, ISO swapping keys */
+#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */
+#define ADB_HANDLER_CLASSIC1_MOUSE 0x01
+#define ADB_HANDLER_CLASSIC2_MOUSE 0x02
+#define ADB_HANDLER_EXTENDED_MOUSE 0x04
+#define ADB_HANDLER_TURBO_MOUSE 0x32
+
// ADB host
void adb_host_init(void);
bool adb_host_psw(void);
+uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
+uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
+void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
+void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
+void adb_host_flush(uint8_t addr);
+void adb_host_kbd_led(uint8_t led);
uint16_t adb_host_kbd_recv(void);
uint16_t adb_host_mouse_recv(void);
-void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l);
-void adb_host_kbd_led(uint8_t led);
-void adb_mouse_task(void);
-void adb_mouse_init(void);
+
+// ADB Mouse
+void adb_mouse_task(void);
+void adb_mouse_init(void);
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c
index d3319ab447..dda2f85b00 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.c
+++ b/tmk_core/protocol/arm_atsam/i2c_master.c
@@ -28,6 +28,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers
+DmacDescriptor dmac_desc;
+DmacDescriptor dmac_desc_wb;
+
static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer
static uint8_t i2c_led_q_s; // Start of circular buffer
static uint8_t i2c_led_q_e; // End of circular buffer
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.h b/tmk_core/protocol/arm_atsam/i2c_master.h
index 44dbdfbffa..68773f213f 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.h
+++ b/tmk_core/protocol/arm_atsam/i2c_master.h
@@ -24,8 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "issi3733_driver.h"
# include "config.h"
-__attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
-__attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
+extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
+extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
uint8_t I2C3733_Init_Control(void);
uint8_t I2C3733_Init_Drivers(void);
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
index e10be52fb8..ab5e9a9852 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -305,11 +305,5 @@ int main(void) {
// dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired);
}
#endif // CONSOLE_ENABLE
-
- // Run housekeeping
- housekeeping_task_kb();
- housekeeping_task_user();
- }
-
return 1;
}
diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c b/tmk_core/protocol/arm_atsam/md_rgb_matrix.c
index b337df7627..2b0805dc86 100644
--- a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c
+++ b/tmk_core/protocol/arm_atsam/md_rgb_matrix.c
@@ -15,16 +15,17 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "arm_atsam_protocol.h"
-#include "tmk_core/common/led.h"
-#include "rgb_matrix.h"
-#include <string.h>
-#include <math.h>
-
-#ifdef USE_MASSDROP_CONFIGURATOR
+#ifdef RGB_MATRIX_ENABLE
+# include "arm_atsam_protocol.h"
+# include "led.h"
+# include "rgb_matrix.h"
+# include <string.h>
+# include <math.h>
+
+# ifdef USE_MASSDROP_CONFIGURATOR
__attribute__((weak)) led_instruction_t led_instructions[] = {{.end = 1}};
static void md_rgb_matrix_config_override(int i);
-#endif // USE_MASSDROP_CONFIGURATOR
+# endif // USE_MASSDROP_CONFIGURATOR
void SERCOM1_0_Handler(void) {
if (SERCOM1->I2CM.INTFLAG.bit.ERROR) {
@@ -58,17 +59,17 @@ RGB led_buffer[ISSI3733_LED_COUNT];
uint8_t gcr_desired;
uint8_t gcr_actual;
uint8_t gcr_actual_last;
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
uint8_t gcr_breathe;
float breathe_mult;
float pomod;
-#endif
+# endif
-#define ACT_GCR_NONE 0
-#define ACT_GCR_INC 1
-#define ACT_GCR_DEC 2
+# define ACT_GCR_NONE 0
+# define ACT_GCR_INC 1
+# define ACT_GCR_DEC 2
-#define LED_GCR_STEP_AUTO 2
+# define LED_GCR_STEP_AUTO 2
static uint8_t gcr_min_counter;
static uint8_t v_5v_cat_hit;
@@ -78,11 +79,11 @@ void gcr_compute(void) {
uint8_t action = ACT_GCR_NONE;
uint8_t gcr_use = gcr_desired;
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
if (led_animation_breathing) {
gcr_use = gcr_breathe;
}
-#endif
+# endif
// If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over
if (v_5v < V5_CAT) {
@@ -150,7 +151,7 @@ void gcr_compute(void) {
gcr_actual -= LED_GCR_STEP_AUTO;
gcr_min_counter = 0;
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
// If breathe mode is active, the top end can fluctuate if the host can not supply enough current
// So set the breathe GCR to where it becomes stable
if (led_animation_breathing == 1) {
@@ -159,7 +160,7 @@ void gcr_compute(void) {
// and the same would happen maybe one or two more times. Therefore I'm favoring
// powering through one full breathe and letting gcr settle completely
}
-#endif
+# endif
}
}
}
@@ -196,25 +197,25 @@ void md_rgb_matrix_prepare(void) {
}
}
-void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) {
+static void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) {
if (i < ISSI3733_LED_COUNT) {
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
md_rgb_matrix_config_override(i);
-#else
+# else
led_buffer[i].r = r;
led_buffer[i].g = g;
led_buffer[i].b = b;
-#endif
+# endif
}
}
-void led_set_all(uint8_t r, uint8_t g, uint8_t b) {
+static void led_set_all(uint8_t r, uint8_t g, uint8_t b) {
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
led_set_one(i, r, g, b);
}
}
-void init(void) {
+static void init(void) {
DBGC(DC_LED_MATRIX_INIT_BEGIN);
issi3733_prepare_arrays();
@@ -227,16 +228,16 @@ void init(void) {
DBGC(DC_LED_MATRIX_INIT_COMPLETE);
}
-void flush(void) {
-#ifdef USE_MASSDROP_CONFIGURATOR
+static void flush(void) {
+# ifdef USE_MASSDROP_CONFIGURATOR
if (!led_enabled) {
return;
} // Prevent calculations and I2C traffic if LED drivers are not enabled
-#else
+# else
if (!sr_exp_data.bit.SDB_N) {
return;
} // Prevent calculations and I2C traffic if LED drivers are not enabled
-#endif
+# endif
// Wait for previous transfer to complete
while (i2c_led_q_running) {
@@ -249,7 +250,7 @@ void flush(void) {
*led_map[i].rgb.b = led_buffer[i].b;
}
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
breathe_mult = 1;
if (led_animation_breathing) {
@@ -275,7 +276,7 @@ void flush(void) {
pomod = (uint32_t)pomod % 10000;
pomod /= 100.0f;
-#endif // USE_MASSDROP_CONFIGURATOR
+# endif // USE_MASSDROP_CONFIGURATOR
uint8_t drvid;
@@ -295,25 +296,27 @@ void md_rgb_matrix_indicators(void) {
if (kbled && rgb_matrix_config.enable) {
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
if (
-#if USB_LED_NUM_LOCK_SCANCODE != 255
+# if USB_LED_NUM_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && (kbled & (1 << USB_LED_NUM_LOCK))) ||
-#endif // NUM LOCK
-#if USB_LED_CAPS_LOCK_SCANCODE != 255
+# endif // NUM LOCK
+# if USB_LED_CAPS_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && (kbled & (1 << USB_LED_CAPS_LOCK))) ||
-#endif // CAPS LOCK
-#if USB_LED_SCROLL_LOCK_SCANCODE != 255
+# endif // CAPS LOCK
+# if USB_LED_SCROLL_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && (kbled & (1 << USB_LED_SCROLL_LOCK))) ||
-#endif // SCROLL LOCK
-#if USB_LED_COMPOSE_SCANCODE != 255
+# endif // SCROLL LOCK
+# if USB_LED_COMPOSE_SCANCODE != 255
(led_map[i].scan == USB_LED_COMPOSE_SCANCODE && (kbled & (1 << USB_LED_COMPOSE))) ||
-#endif // COMPOSE
-#if USB_LED_KANA_SCANCODE != 255
+# endif // COMPOSE
+# if USB_LED_KANA_SCANCODE != 255
(led_map[i].scan == USB_LED_KANA_SCANCODE && (kbled & (1 << USB_LED_KANA))) ||
-#endif // KANA
+# endif // KANA
(0)) {
- led_buffer[i].r = 255 - led_buffer[i].r;
- led_buffer[i].g = 255 - led_buffer[i].g;
- led_buffer[i].b = 255 - led_buffer[i].b;
+ if (rgb_matrix_get_flags() & LED_FLAG_INDICATOR) {
+ led_buffer[i].r = 255 - led_buffer[i].r;
+ led_buffer[i].g = 255 - led_buffer[i].g;
+ led_buffer[i].b = 255 - led_buffer[i].b;
+ }
}
}
}
@@ -325,7 +328,7 @@ const rgb_matrix_driver_t rgb_matrix_driver = {.init = init, .flush = flush, .se
= Legacy Lighting Support =
==============================================================================*/
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
// Ported from Massdrop QMK GitHub Repo
// TODO?: wire these up to keymap.c
@@ -467,4 +470,5 @@ static void md_rgb_matrix_config_override(int i) {
led_buffer[i].b = (uint8_t)bo;
}
-#endif // USE_MASSDROP_CONFIGURATOR
+# endif // USE_MASSDROP_CONFIGURATOR
+#endif // RGB_MATRIX_ENABLE
diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c b/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c
index b43008cc5b..fce225a6c4 100644
--- a/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c
+++ b/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c
@@ -15,9 +15,10 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifdef USE_MASSDROP_CONFIGURATOR
+#ifdef RGB_MATRIX_ENABLE
+# ifdef USE_MASSDROP_CONFIGURATOR
-# include "md_rgb_matrix.h"
+# include "md_rgb_matrix.h"
// Teal <-> Salmon
led_setup_t leds_teal_salmon[] = {
@@ -96,4 +97,5 @@ void *led_setups[] = {leds_rainbow_s, leds_rainbow_ns, leds_teal_salmon, leds_ye
const uint8_t led_setups_count = sizeof(led_setups) / sizeof(led_setups[0]);
-#endif
+# endif // USE_MASSDROP_CONFIGURATOR
+#endif // RGB_MATRIX_ENABLE
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
index e3fa65574e..9ea4addcfc 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
+++ b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
@@ -374,39 +374,33 @@ static uint8_t udi_hid_exk_report_trans[UDI_HID_EXK_REPORT_SIZE];
COMPILER_WORD_ALIGNED
UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {{
+ // clang-format off
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x80, // Usage (System Control)
0xA1, 0x01, // Collection (Application)
0x85, REPORT_ID_SYSTEM, // Report ID
- 0x1A, 0x81,
- 0x00, // Usage Minimum (81) (System Power Down)
- 0x2A, 0x83,
- 0x00, // Usage Maximum (83) (System Wake Up)
- 0x16, 0x01,
- 0x00, // Logical Minimum (1)
- 0x26, 0x03,
- 0x00, // Logical Maximum (3)
- 0x95, 0x01, // Report Count (1)
- 0x75, 0x10, // Report Size (16)
- 0x81, 0x00, // Input (Data, Array, Absolute)
- 0xC0, // End Collection
+ 0x19, 0x01, // Usage Minimum (Pointer)
+ 0x2A, 0xB7, 0x00, // Usage Maximum (System Display LCD Autoscale)
+ 0x15, 0x01, // Logical Minimum
+ 0x26, 0xB7, 0x00, // Logical Maximum
+ 0x95, 0x01, // Report Count (1)
+ 0x75, 0x10, // Report Size (16)
+ 0x81, 0x00, // Input (Data, Array, Absolute)
+ 0xC0, // End Collection
0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x01, // Usage (Consumer Control)
0xA1, 0x01, // Collection (Application)
0x85, REPORT_ID_CONSUMER, // Report ID
- 0x1A, 0x01,
- 0x00, // Usage Minimum (Consumer Control)
- 0x2A, 0x9C,
- 0x02, // Usage Maximum (AC Distribute Vertically)
- 0x16, 0x01,
- 0x00, // Logical Minimum
- 0x26, 0x9C,
- 0x02, // Logical Maximum
- 0x95, 0x01, // Report Count (1)
- 0x75, 0x10, // Report Size (16)
- 0x81, 0x00, // Input (Data, Array, Absolute)
- 0xC0 // End Collection
+ 0x19, 0x01, // Usage Minimum (Consumer Control)
+ 0x2A, 0xA0, 0x02, // Usage Maximum (AC Desktop Show All Applications)
+ 0x15, 0x01, // Logical Minimum
+ 0x26, 0xA0, 0x02, // Logical Maximum
+ 0x95, 0x01, // Report Count (1)
+ 0x75, 0x10, // Report Size (16)
+ 0x81, 0x00, // Input (Data, Array, Absolute)
+ 0xC0 // End Collection
+ //clang-format on
}};
static bool udi_hid_exk_setreport(void);
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h b/tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h
index 2f8a39bdd8..fb97f63cef 100644
--- a/tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h
+++ b/tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h
@@ -186,9 +186,10 @@ COMPILER_PACK_RESET()
#define USB_HID_COUNTRY_UK 32 // UK
#define USB_HID_COUNTRY_US 33 // US
#define USB_HID_COUNTRY_YUGOSLAVIA 34 // Yugoslavia
-#define USB_HID_COUNTRY_TURKISH_F 35 // Turkish-F
- //! @}
- //! @}
+#define USB_HID_COUNTRY_TURKISH_F \
+ 35 // Turkish-F
+ //! @}
+ //! @}
//! @}
//! \name HID KEYS values
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index 5c27a8c6a0..6cd88be577 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -167,6 +167,7 @@ int main(void) {
keyboard_setup();
/* Init USB */
+ usb_event_queue_init();
init_usb_driver(&USB_DRIVER);
#ifdef MIDI_ENABLE
@@ -225,6 +226,8 @@ int main(void) {
/* Main loop */
while (true) {
+ usb_event_queue_task();
+
#if !defined(NO_USB_STARTUP_CHECK)
if (USB_DRIVER.state == USB_SUSPENDED) {
print("[s]");
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index 67ae8520fd..990dc1b91c 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -27,6 +27,7 @@
#include <ch.h>
#include <hal.h>
+#include <string.h>
#include "usb_main.h"
@@ -50,6 +51,7 @@ extern keymap_config_t keymap_config;
#ifdef WEBUSB_ENABLE
# include "webusb.h"
#endif
+
#ifdef JOYSTICK_ENABLE
# include "joystick.h"
#endif
@@ -168,6 +170,7 @@ static const USBEndpointConfig shared_ep_config = {
};
#endif
+
#ifdef WEBUSB_ENABLE
/** Microsoft OS 2.0 Descriptor. This is used by Windows to select the USB driver for the device.
*
@@ -397,6 +400,69 @@ static usb_driver_configs_t drivers = {
* ---------------------------------------------------------
*/
+#define USB_EVENT_QUEUE_SIZE 16
+usbevent_t event_queue[USB_EVENT_QUEUE_SIZE];
+uint8_t event_queue_head;
+uint8_t event_queue_tail;
+
+void usb_event_queue_init(void) {
+ // Initialise the event queue
+ memset(&event_queue, 0, sizeof(event_queue));
+ event_queue_head = 0;
+ event_queue_tail = 0;
+}
+
+static inline bool usb_event_queue_enqueue(usbevent_t event) {
+ uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE;
+ if (next == event_queue_tail) {
+ return false;
+ }
+ event_queue[event_queue_head] = event;
+ event_queue_head = next;
+ return true;
+}
+
+static inline bool usb_event_queue_dequeue(usbevent_t *event) {
+ if (event_queue_head == event_queue_tail) {
+ return false;
+ }
+ *event = event_queue[event_queue_tail];
+ event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE;
+ return true;
+}
+
+static inline void usb_event_suspend_handler(void) {
+#ifdef SLEEP_LED_ENABLE
+ sleep_led_enable();
+#endif /* SLEEP_LED_ENABLE */
+}
+
+static inline void usb_event_wakeup_handler(void) {
+ suspend_wakeup_init();
+#ifdef SLEEP_LED_ENABLE
+ sleep_led_disable();
+ // NOTE: converters may not accept this
+ led_set(host_keyboard_leds());
+#endif /* SLEEP_LED_ENABLE */
+}
+
+void usb_event_queue_task(void) {
+ usbevent_t event;
+ while (usb_event_queue_dequeue(&event)) {
+ switch (event) {
+ case USB_EVENT_SUSPEND:
+ usb_event_suspend_handler();
+ break;
+ case USB_EVENT_WAKEUP:
+ usb_event_wakeup_handler();
+ break;
+ default:
+ // Nothing to do, we don't handle it.
+ break;
+ }
+ }
+}
+
/* Handles the USB driver global events
* TODO: maybe disable some things when connection is lost? */
static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
@@ -431,9 +497,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
osalSysUnlockFromISR();
return;
case USB_EVENT_SUSPEND:
-#ifdef SLEEP_LED_ENABLE
- sleep_led_enable();
-#endif /* SLEEP_LED_ENABLE */
+ usb_event_queue_enqueue(USB_EVENT_SUSPEND);
/* Falls into.*/
case USB_EVENT_UNCONFIGURED:
/* Falls into.*/
@@ -454,12 +518,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
qmkusbWakeupHookI(&drivers.array[i].driver);
chSysUnlockFromISR();
}
- suspend_wakeup_init();
-#ifdef SLEEP_LED_ENABLE
- sleep_led_disable();
- // NOTE: converters may not accept this
- led_set(host_keyboard_leds());
-#endif /* SLEEP_LED_ENABLE */
+ usb_event_queue_enqueue(USB_EVENT_WAKEUP);
return;
case USB_EVENT_STALLED:
@@ -575,7 +634,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
if (!keymap_config.nkro && keyboard_idle) {
#else /* NKRO_ENABLE */
if (keyboard_idle) {
-#endif /* NKRO_ENABLE */
+#endif /* NKRO_ENABLE */
/* arm the idle timer if boot protocol & idle */
osalSysLockFromISR();
chVTSetI(&keyboard_idle_timer, 4 * TIME_MS2I(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
@@ -867,7 +926,7 @@ void send_mouse(report_mouse_t *report) {
}
#else /* MOUSE_ENABLE */
-void send_mouse(report_mouse_t *report) { (void)report; }
+void send_mouse(report_mouse_t *report) { (void)report; }
#endif /* MOUSE_ENABLE */
/* ---------------------------------------------------------
@@ -923,9 +982,32 @@ void send_consumer(uint16_t data) {
#ifdef CONSOLE_ENABLE
int8_t sendchar(uint8_t c) {
- // The previous implmentation had timeouts, but I think it's better to just slow down
- // and make sure that everything is transferred, rather than dropping stuff
- return chnWrite(&drivers.console_driver.driver, &c, 1);
+ static bool timed_out = false;
+ /* The `timed_out` state is an approximation of the ideal `is_listener_disconnected?` state.
+ *
+ * When a 5ms timeout write has timed out, hid_listen is most likely not running, or not
+ * listening to this keyboard, so we go into the timed_out state. In this state we assume
+ * that hid_listen is most likely not gonna be connected to us any time soon, so it would
+ * be wasteful to write follow-up characters with a 5ms timeout, it would all add up and
+ * unncecessarily slow down the firmware. However instead of just dropping the characters,
+ * we write them with a TIME_IMMEDIATE timeout, which is a zero timeout,
+ * and this will succeed only if hid_listen gets connected again. When a write with
+ * TIME_IMMEDIATE timeout succeeds, we know that hid_listen is listening to us again, and
+ * we can go back to the timed_out = false state, and following writes will be executed
+ * with a 5ms timeout. The reason we don't just send all characters with the TIME_IMMEDIATE
+ * timeout is that this could cause bytes to be lost even if hid_listen is running, if there
+ * is a lot of data being sent over the console.
+ *
+ * This logic will work correctly as long as hid_listen is able to receive at least 200
+ * bytes per second. On a heavily overloaded machine that's so overloaded that it's
+ * unusable, and constantly swapping, hid_listen might have trouble receiving 200 bytes per
+ * second, so some bytes might be lost on the console.
+ */
+
+ const sysinterval_t timeout = timed_out ? TIME_IMMEDIATE : TIME_MS2I(5);
+ const size_t result = chnWriteTimeout(&drivers.console_driver.driver, &c, 1, timeout);
+ timed_out = (result == 0);
+ return result;
}
// Just a dummy function for now, this could be exposed as a weak function
@@ -946,15 +1028,8 @@ void console_task(void) {
} while (size > 0);
}
-#else /* CONSOLE_ENABLE */
-int8_t sendchar(uint8_t c) {
- (void)c;
- return 0;
-}
#endif /* CONSOLE_ENABLE */
-void _putchar(char character) { sendchar(character); }
-
#ifdef RAW_ENABLE
void raw_hid_send(uint8_t *data, uint8_t length) {
// TODO: implement variable size packet
diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h
index eaa08d8f79..fb33c8cd0f 100644
--- a/tmk_core/protocol/chibios/usb_main.h
+++ b/tmk_core/protocol/chibios/usb_main.h
@@ -38,6 +38,17 @@ void init_usb_driver(USBDriver *usbp);
void restart_usb_driver(USBDriver *usbp);
/* ---------------
+ * USB Event queue
+ * ---------------
+ */
+
+/* Initialisation of the FIFO */
+void usb_event_queue_init(void);
+
+/* Task to dequeue and execute any handlers for the USB events on the main thread */
+void usb_event_queue_task(void);
+
+/* ---------------
* Keyboard header
* ---------------
*/
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 1d019d1695..b1af36d113 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -782,9 +782,7 @@ static void send_keyboard(report_keyboard_t *report) {
uint8_t timeout = 255;
#ifdef BLUETOOTH_ENABLE
- uint8_t where = where_to_send();
-
- if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
+ if (where_to_send() == OUTPUT_BLUETOOTH) {
# ifdef MODULE_ADAFRUIT_BLE
adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
# elif MODULE_RN42
@@ -797,9 +795,6 @@ static void send_keyboard(report_keyboard_t *report) {
serial_send(report->keys[i]);
}
# endif
- }
-
- if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
return;
}
#endif
@@ -840,9 +835,7 @@ static void send_mouse(report_mouse_t *report) {
uint8_t timeout = 255;
# ifdef BLUETOOTH_ENABLE
- uint8_t where = where_to_send();
-
- if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
+ if (where_to_send() == OUTPUT_BLUETOOTH) {
# ifdef MODULE_ADAFRUIT_BLE
// FIXME: mouse buttons
adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
@@ -857,9 +850,6 @@ static void send_mouse(report_mouse_t *report) {
serial_send(report->h); // should try sending the wheel h here
serial_send(0x00);
# endif
- }
-
- if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
return;
}
# endif
@@ -918,9 +908,13 @@ static void send_system(uint16_t data) {
static void send_consumer(uint16_t data) {
#ifdef EXTRAKEY_ENABLE
# ifdef BLUETOOTH_ENABLE
+<<<<<<< HEAD
uint8_t where = where_to_send();
if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
+=======
+ if (where_to_send() == OUTPUT_BLUETOOTH) {
+>>>>>>> 0.12.52~1
# ifdef MODULE_ADAFRUIT_BLE
adafruit_ble_send_consumer_key(data);
# elif MODULE_RN42
@@ -934,9 +928,12 @@ static void send_consumer(uint16_t data) {
serial_send(bitmap & 0xFF);
serial_send((bitmap >> 8) & 0xFF);
# endif
+<<<<<<< HEAD
}
if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
+=======
+>>>>>>> 0.12.52~1
return;
}
# endif
@@ -955,9 +952,14 @@ static void send_consumer(uint16_t data) {
* FIXME: Needs doc
*/
int8_t sendchar(uint8_t c) {
+<<<<<<< HEAD
// Not wait once timeouted.
+=======
+ // Do not wait if the previous write has timed_out.
+>>>>>>> 0.12.52~1
// Because sendchar() is called so many times, waiting each call causes big lag.
- static bool timeouted = false;
+ // The `timed_out` state is an approximation of the ideal `is_listener_disconnected?` state.
+ static bool timed_out = false;
// prevents Console_Task() from running during sendchar() runs.
// or char will be lost. These two function is mutually exclusive.
@@ -971,11 +973,11 @@ int8_t sendchar(uint8_t c) {
goto ERROR_EXIT;
}
- if (timeouted && !Endpoint_IsReadWriteAllowed()) {
+ if (timed_out && !Endpoint_IsReadWriteAllowed()) {
goto ERROR_EXIT;
}
- timeouted = false;
+ timed_out = false;
uint8_t timeout = SEND_TIMEOUT;
while (!Endpoint_IsReadWriteAllowed()) {
@@ -986,7 +988,7 @@ int8_t sendchar(uint8_t c) {
goto ERROR_EXIT;
}
if (!(timeout--)) {
- timeouted = true;
+ timed_out = true;
goto ERROR_EXIT;
}
_delay_ms(1);
@@ -1136,7 +1138,6 @@ static void setup_usb(void) {
// for Console_Task
USB_Device_EnableSOFEvents();
- print_set_sendchar(sendchar);
}
/** \brief Main
diff --git a/tmk_core/protocol/lufa/outputselect.h b/tmk_core/protocol/lufa/outputselect.h
index 7f7ed00b95..c4548e1122 100644
--- a/tmk_core/protocol/lufa/outputselect.h
+++ b/tmk_core/protocol/lufa/outputselect.h
@@ -21,21 +21,11 @@ enum outputs {
OUTPUT_NONE,
OUTPUT_USB,
- OUTPUT_BLUETOOTH,
-
- // backward compatibility
- OUTPUT_USB_AND_BT
+ OUTPUT_BLUETOOTH
};
-/**
- * backward compatibility for BLUETOOTH_ENABLE, send to BT and USB by default
- */
#ifndef OUTPUT_DEFAULT
-# ifdef BLUETOOTH_ENABLE
-# define OUTPUT_DEFAULT OUTPUT_USB_AND_BT
-# else
-# define OUTPUT_DEFAULT OUTPUT_AUTO
-# endif
+# define OUTPUT_DEFAULT OUTPUT_AUTO
#endif
void set_output(uint8_t output);
diff --git a/tmk_core/protocol/m0110.c b/tmk_core/protocol/m0110.c
index b02a6933d2..64f2fa50ab 100644
--- a/tmk_core/protocol/m0110.c
+++ b/tmk_core/protocol/m0110.c
@@ -95,11 +95,11 @@ void m0110_init(void) {
uint8_t data;
m0110_send(M0110_MODEL);
data = m0110_recv();
- print("m0110_init model: "); phex(data); print("\n");
+ print("m0110_init model: "); print_hex8(data); print("\n");
m0110_send(M0110_TEST);
data = m0110_recv();
- print("m0110_init test: "); phex(data); print("\n");
+ print("m0110_init test: "); print_hex8(data); print("\n");
*/
}
@@ -122,7 +122,7 @@ uint8_t m0110_send(uint8_t data) {
return 1;
ERROR:
print("m0110_send err: ");
- phex(m0110_error);
+ print_hex8(m0110_error);
print("\n");
_delay_ms(500);
idle();
@@ -146,7 +146,7 @@ uint8_t m0110_recv(void) {
return data;
ERROR:
print("m0110_recv err: ");
- phex(m0110_error);
+ print_hex8(m0110_error);
print("\n");
_delay_ms(500);
idle();
diff --git a/tmk_core/protocol/midi/qmk_midi.c b/tmk_core/protocol/midi/qmk_midi.c
index 6f6aced725..c18dbf9930 100644
--- a/tmk_core/protocol/midi/qmk_midi.c
+++ b/tmk_core/protocol/midi/qmk_midi.c
@@ -5,7 +5,7 @@
#include "usb_descriptor.h"
#include "process_midi.h"
#if API_SYSEX_ENABLE
-# include "api.h"
+# include "api_sysex.h"
#endif
/*******************************************************************************
diff --git a/tmk_core/protocol/ps2_mouse.c b/tmk_core/protocol/ps2_mouse.c
index 8df465026b..5415453a05 100644
--- a/tmk_core/protocol/ps2_mouse.c
+++ b/tmk_core/protocol/ps2_mouse.c
@@ -190,7 +190,7 @@ static inline void ps2_mouse_clear_report(report_mouse_t *mouse_report) {
static inline void ps2_mouse_print_report(report_mouse_t *mouse_report) {
if (!debug_mouse) return;
print("ps2_mouse: [");
- phex(mouse_report->buttons);
+ print_hex8(mouse_report->buttons);
print("|");
print_hex8((uint8_t)mouse_report->x);
print(" ");
diff --git a/tmk_core/protocol/serial.h b/tmk_core/protocol/serial.h
index b70d117d7c..0204b84a92 100644
--- a/tmk_core/protocol/serial.h
+++ b/tmk_core/protocol/serial.h
@@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE.
#pragma once
+#define SERIAL_UART_DATA UDR1
+
/* host role */
void serial_init(void);
uint8_t serial_recv(void);
diff --git a/tmk_core/protocol/serial_uart.c b/tmk_core/protocol/serial_uart.c
index a15124193a..d5b5657095 100644
--- a/tmk_core/protocol/serial_uart.c
+++ b/tmk_core/protocol/serial_uart.c
@@ -40,6 +40,22 @@ POSSIBILITY OF SUCH DAMAGE.
#include <avr/interrupt.h>
#include "serial.h"
+#ifndef SERIAL_UART_BAUD
+# define SERIAL_UART_BAUD 9600
+#endif
+
+#define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1)
+#define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1))
+#define SERIAL_UART_RXD_VECT USART1_RX_vect
+
+#ifndef SERIAL_UART_INIT_CUSTOM
+# define SERIAL_UART_INIT_CUSTOM \
+ /* enable TX */ \
+ UCSR1B = _BV(TXEN1); \
+ /* 8-bit data */ \
+ UCSR1C = _BV(UCSZ11) | _BV(UCSZ10);
+#endif
+
#if defined(SERIAL_UART_RTS_LO) && defined(SERIAL_UART_RTS_HI)
// Buffer state
// Empty: RBUF_SPACE == RBUF_SIZE(head==tail)
@@ -61,7 +77,14 @@ POSSIBILITY OF SUCH DAMAGE.
# define rbuf_check_rts_hi()
#endif
-void serial_init(void) { SERIAL_UART_INIT(); }
+void serial_init(void) {
+ do {
+ // Set baud rate
+ UBRR1L = SERIAL_UART_UBRR;
+ UBRR1L = SERIAL_UART_UBRR >> 8;
+ SERIAL_UART_INIT_CUSTOM;
+ } while (0);
+}
// RX ring buffer
#define RBUF_SIZE 256
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index 4a5edb1907..9277554856 100644
--- a/tmk_core/protocol/usb_descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -40,7 +40,7 @@
#include "report.h"
#include "usb_descriptor.h"
#ifdef WEBUSB_ENABLE
-#include "webusb_descriptor.h"
+# include "webusb_descriptor.h"
#endif
#include "usb_descriptor_common.h"
@@ -119,19 +119,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
# endif
HID_RI_USAGE(8, 0x01), // Pointer
HID_RI_COLLECTION(8, 0x00), // Physical
- // Buttons (5 bits)
+ // Buttons (8 bits)
HID_RI_USAGE_PAGE(8, 0x09), // Button
HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
- HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5
+ HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
- HID_RI_REPORT_COUNT(8, 0x05),
+ HID_RI_REPORT_COUNT(8, 0x08),
HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
- // Button padding (3 bits)
- HID_RI_REPORT_COUNT(8, 0x01),
- HID_RI_REPORT_SIZE(8, 0x03),
- HID_RI_INPUT(8, HID_IOF_CONSTANT),
// X/Y position (2 bytes)
HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
@@ -288,8 +284,8 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = {
#ifdef WEBUSB_ENABLE
const USB_Descriptor_BOS_t PROGMEM BOSDescriptor = BOS_DESCRIPTOR(
- (MS_OS_20_PLATFORM_DESCRIPTOR(MS_OS_20_VENDOR_CODE, MS_OS_20_DESCRIPTOR_SET_TOTAL_LENGTH))
- (WEBUSB_PLATFORM_DESCRIPTOR(WEBUSB_VENDOR_CODE, WEBUSB_LANDING_PAGE_INDEX))
+ (MS_OS_20_PLATFORM_DESCRIPTOR(MS_OS_20_VENDOR_CODE, MS_OS_20_DESCRIPTOR_SET_TOTAL_LENGTH))
+ (WEBUSB_PLATFORM_DESCRIPTOR(WEBUSB_VENDOR_CODE, WEBUSB_LANDING_PAGE_INDEX))
);
#endif
#ifdef JOYSTICK_ENABLE
@@ -369,6 +365,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
#else
.USBSpecification = VERSION_BCD(1, 1, 0),
#endif
+
#if VIRTSER_ENABLE
.Class = USB_CSCP_IADDeviceClass,
.SubClass = USB_CSCP_IADDeviceSubclass,
diff --git a/tmk_core/protocol/usb_descriptor.h b/tmk_core/protocol/usb_descriptor.h
index e4d5435110..2ea4861f36 100644
--- a/tmk_core/protocol/usb_descriptor.h
+++ b/tmk_core/protocol/usb_descriptor.h
@@ -49,7 +49,7 @@
# include <hal.h>
#endif
#ifdef WEBUSB_ENABLE
-#include "webusb_descriptor.h"
+# include "webusb_descriptor.h"
#endif
/*
@@ -271,6 +271,7 @@ enum usb_endpoints {
# define WEBUSB_IN_EPADDR (ENDPOINT_DIR_IN | WEBUSB_IN_EPNUM)
# define WEBUSB_OUT_EPADDR (ENDPOINT_DIR_OUT | WEBUSB_OUT_EPNUM)
#endif
+
#ifdef JOYSTICK_ENABLE
JOYSTICK_IN_EPNUM = NEXT_EPNUM,
# if STM32_USB_USE_OTG1
diff --git a/tmk_core/protocol/usb_hid/test/Makefile b/tmk_core/protocol/usb_hid/test/Makefile
deleted file mode 100644
index 83bf2aed67..0000000000
--- a/tmk_core/protocol/usb_hid/test/Makefile
+++ /dev/null
@@ -1,126 +0,0 @@
-#----------------------------------------------------------------------------
-# On command line:
-#
-# make all = Make software.
-#
-# make clean = Clean out built project files.
-#
-# make coff = Convert ELF to AVR COFF.
-#
-# make extcoff = Convert ELF to AVR Extended COFF.
-#
-# make program = Download the hex file to the device.
-# Please customize your programmer settings(PROGRAM_CMD)
-#
-# make teensy = Download the hex file to the device, using teensy_loader_cli.
-# (must have teensy_loader_cli installed).
-#
-# make dfu = Download the hex file to the device, using dfu-programmer (must
-# have dfu-programmer installed).
-#
-# make flip = Download the hex file to the device, using Atmel FLIP (must
-# have Atmel FLIP installed).
-#
-# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
-# (must have dfu-programmer installed).
-#
-# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
-# (must have Atmel FLIP installed).
-#
-# make debug = Start either simulavr or avarice as specified for debugging,
-# with avr-gdb or avr-insight as the front end for debugging.
-#
-# make filename.s = Just compile filename.c into the assembler code only.
-#
-# make filename.i = Create a preprocessed source file for use in submitting
-# bug reports to the GCC project.
-#
-# To rebuild project do "make clean" then "make all".
-#----------------------------------------------------------------------------
-
-# Target file name (without extension).
-TARGET = usb_hid_test
-
-TMK_DIR = ../../..
-
-# Directory keyboard dependent files exist
-TARGET_DIR = .
-
-# MCU name
-MCU = atmega32u4
-
-
-# Processor frequency.
-# This will define a symbol, F_CPU, in all source code files equal to the
-# processor frequency in Hz. You can then use this symbol in your source code to
-# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
-# automatically to create a 32-bit value in your source code.
-#
-# This will be an integer division of F_USB below, as it is sourced by
-# F_USB after it has run through any CPU prescalers. Note that this value
-# does not *change* the processor frequency - it should merely be updated to
-# reflect the processor speed set externally so that the code can use accurate
-# software delays.
-F_CPU = 16000000
-
-
-
-#
-# LUFA specific
-#
-# Target architecture (see library "Board Types" documentation).
-ARCH = AVR8
-# Input clock frequency.
-# This will define a symbol, F_USB, in all source code files equal to the
-# input clock frequency (before any prescaling is performed) in Hz. This value may
-# differ from F_CPU if prescaling is used on the latter, and is required as the
-# raw input clock is fed directly to the PLL sections of the AVR for high speed
-# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
-# at the end, this will be done automatically to create a 32-bit value in your
-# source code.
-#
-# If no clock division is performed on the input clock inside the AVR (via the
-# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
-F_USB = $(F_CPU)
-# Interrupt driven control endpoint task
-OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
-
-
-
-# Build Options
-# comment out to disable the options.
-#
-# Console for debug
-OPT_DEFS += -DCONSOLE_ENABLE
-
-# Boot Section Size in bytes
-# Teensy halfKay 512
-# Atmel DFU loader 4096
-# LUFA bootloader 4096
-#OPT_DEFS += -DBOOT_SIZE=4096
-
-
-
-SRC = test.cpp
-SRC += common/debug.c
-SRC += common/print.c
-
-CONFIG_H = config.h
-
-
-
-# Search Path
-VPATH += $(TARGET_DIR)
-VPATH += $(TMK_DIR)
-VPATH += $(TMK_DIR)/common
-
-
-
-# program Leonardo
-PROGRAM_CMD = avrdude -p$(MCU) -cavr109 -P$(DEV) -b57600 -Uflash:w:$(TARGET).hex
-
-
-
-include $(TMK_DIR)/protocol/usb_hid.mk
-include $(TMK_DIR)/protocol/lufa.mk
-include $(TMK_DIR)/rules.mk
diff --git a/tmk_core/protocol/usb_hid/test/config.h b/tmk_core/protocol/usb_hid/test/config.h
deleted file mode 100644
index 71a6814fd1..0000000000
--- a/tmk_core/protocol/usb_hid/test/config.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-Copyright 2012 Jun Wako <wakojun@gmail.com>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#define VENDOR_ID 0xFEED
-#define PRODUCT_ID 0xCAFE
-#define DEVICE_VER 0x0814
-#define MANUFACTURER t.m.k.
-#define PRODUCT USB to USB keyboard converter
-
-#define DESCRIPTION Product from t.m.k. keyboard firmware project
-
-/* matrix size */
-#define MATRIX_ROWS 32
-#define MATRIX_COLS 8
diff --git a/tmk_core/protocol/usb_hid/test/test.cpp b/tmk_core/protocol/usb_hid/test/test.cpp
deleted file mode 100644
index 4958f0c619..0000000000
--- a/tmk_core/protocol/usb_hid/test/test.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#include <avr/io.h>
-#include <avr/wdt.h>
-#include <avr/power.h>
-#include <util/delay.h>
-#include <Arduino.h>
-
-// USB HID host
-#include "Usb.h"
-#include "hid.h"
-#include "hidboot.h"
-#include "parser.h"
-
-// LUFA
-#include "lufa.h"
-
-#include "debug.h"
-
-#include "leonardo_led.h"
-
-
-static USB usb_host;
-static HIDBoot<HID_PROTOCOL_KEYBOARD> kbd(&usb_host);
-static KBDReportParser kbd_parser;
-
-static void LUFA_setup(void)
-{
- /* Disable watchdog if enabled by bootloader/fuses */
- MCUSR &= ~(1 << WDRF);
- wdt_disable();
-
- /* Disable clock division */
- clock_prescale_set(clock_div_1);
-
- // Leonardo needs. Without this USB device is not recognized.
- USB_Disable();
-
- USB_Init();
-
- // for Console_Task
- USB_Device_EnableSOFEvents();
-}
-
-static void HID_setup()
-{
- // Arduino Timer startup: wiring.c
- init();
-
- if (usb_host.Init() == -1) {
- debug("HID init: failed\n");
- LED_TX_OFF;
- }
-
- _delay_ms(200);
-
- kbd.SetReportParser(0, (HIDReportParser*)&kbd_parser);
-}
-
-int main(void)
-{
- // LED for debug
- LED_TX_INIT;
- LED_TX_ON;
-
- print_enable = true;
- debug_enable = true;
- debug_matrix = true;
- debug_keyboard = true;
- debug_mouse = true;
-
- LUFA_setup();
- sei();
-
- // wait for startup of sendchar routine
- while (USB_DeviceState != DEVICE_STATE_Configured) ;
- if (debug_enable) {
- _delay_ms(1000);
- }
-
- HID_setup();
-
- debug("init: done\n");
- for (;;) {
- usb_host.Task();
-
-#if !defined(INTERRUPT_CONTROL_ENDPOINT)
- // LUFA Task for control request
- USB_USBTask();
-#endif
- }
-
- return 0;
-}
diff --git a/tmk_core/protocol/vusb/main.c b/tmk_core/protocol/vusb/main.c
index 2e8bb2fbbc..53926a7493 100644
--- a/tmk_core/protocol/vusb/main.c
+++ b/tmk_core/protocol/vusb/main.c
@@ -53,10 +53,10 @@ static void initForUsbConnectivity(void) {
usbDeviceConnect();
}
-static void usb_remote_wakeup(void) {
+static void vusb_send_remote_wakeup(void) {
cli();
- int8_t ddr_orig = USBDDR;
+ uint8_t ddr_orig = USBDDR;
USBOUT |= (1 << USBMINUS);
USBDDR = ddr_orig | USBMASK;
USBOUT ^= USBMASK;
@@ -70,16 +70,34 @@ static void usb_remote_wakeup(void) {
sei();
}
+bool vusb_suspended = false;
+
+static void vusb_suspend(void) {
+ vusb_suspended = true;
+
+#ifdef SLEEP_LED_ENABLE
+ sleep_led_enable();
+#endif
+
+ suspend_power_down();
+}
+
+#if USB_COUNT_SOF
+static void vusb_wakeup(void) {
+ vusb_suspended = false;
+ suspend_wakeup_init();
+
+# ifdef SLEEP_LED_ENABLE
+ sleep_led_disable();
+# endif
+}
+#endif
+
/** \brief Setup USB
*
* FIXME: Needs doc
*/
-static void setup_usb(void) {
- initForUsbConnectivity();
-
- // for Console_Task
- print_set_sendchar(sendchar);
-}
+static void setup_usb(void) { initForUsbConnectivity(); }
/** \brief Main
*
@@ -87,9 +105,8 @@ static void setup_usb(void) {
*/
int main(void) __attribute__((weak));
int main(void) {
- bool suspended = false;
#if USB_COUNT_SOF
- uint16_t last_timer = timer_read();
+ uint16_t sof_timer = timer_read();
#endif
#ifdef CLKPR
@@ -112,23 +129,24 @@ int main(void) {
while (1) {
#if USB_COUNT_SOF
if (usbSofCount != 0) {
- suspended = false;
usbSofCount = 0;
- last_timer = timer_read();
-# ifdef SLEEP_LED_ENABLE
- sleep_led_disable();
-# endif
+ sof_timer = timer_read();
+ if (vusb_suspended) {
+ vusb_wakeup();
+ }
} else {
// Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1)
- if (timer_elapsed(last_timer) > 5) {
- suspended = true;
-# ifdef SLEEP_LED_ENABLE
- sleep_led_enable();
-# endif
+ if (!vusb_suspended && timer_elapsed(sof_timer) > 5) {
+ vusb_suspend();
}
}
#endif
- if (!suspended) {
+ if (vusb_suspended) {
+ vusb_suspend();
+ if (suspend_wakeup_condition()) {
+ vusb_send_remote_wakeup();
+ }
+ } else {
usbPoll();
// TODO: configuration process is inconsistent. it sometime fails.
@@ -145,6 +163,7 @@ int main(void) {
raw_hid_task();
}
#endif
+
#ifdef CONSOLE_ENABLE
usbPoll();
@@ -154,10 +173,7 @@ int main(void) {
#endif
// Run housekeeping
- housekeeping_task_kb();
- housekeeping_task_user();
- } else if (suspend_wakeup_condition()) {
- usb_remote_wakeup();
+ housekeeping_task();
}
}
}
diff --git a/tmk_core/protocol/vusb/usbconfig.h b/tmk_core/protocol/vusb/usbconfig.h
new file mode 100644
index 0000000000..041f7bd095
--- /dev/null
+++ b/tmk_core/protocol/vusb/usbconfig.h
@@ -0,0 +1,356 @@
+/* Name: usbconfig.h
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-04-01
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbconfig-prototype.h 785 2010-05-30 17:57:07Z cs $
+ */
+
+#pragma once
+
+// clang-format off
+
+/*
+General Description:
+This file is an example configuration (with inline documentation) for the USB
+driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
+also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
+wire the lines to any other port, as long as D+ is also wired to INT0 (or any
+other hardware interrupt, as long as it is the highest level interrupt, see
+section at the end of this file).
+*/
+
+/* ---------------------------- Hardware Config ---------------------------- */
+
+#ifndef USB_CFG_IOPORTNAME
+#define USB_CFG_IOPORTNAME D
+#endif
+/* This is the port where the USB bus is connected. When you configure it to
+ * "B", the registers PORTB, PINB and DDRB will be used.
+ */
+#ifndef USB_CFG_DMINUS_BIT
+#define USB_CFG_DMINUS_BIT 3
+#endif
+/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
+ * This may be any bit in the port.
+ */
+#ifndef USB_CFG_DPLUS_BIT
+#define USB_CFG_DPLUS_BIT 2
+#endif
+/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
+ * This may be any bit in the port. Please note that D+ must also be connected
+ * to interrupt pin INT0! [You can also use other interrupts, see section
+ * "Optional MCU Description" below, or you can connect D- to the interrupt, as
+ * it is required if you use the USB_COUNT_SOF feature. If you use D- for the
+ * interrupt, the USB interrupt will also be triggered at Start-Of-Frame
+ * markers every millisecond.]
+ */
+#define USB_CFG_CHECK_CRC 0
+/* Define this to 1 if you want that the driver checks integrity of incoming
+ * data packets (CRC checks). CRC checks cost quite a bit of code size and are
+ * currently only available for 18 MHz crystal clock. You must choose
+ * USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
+ */
+
+/* ----------------------- Optional Hardware Config ------------------------ */
+
+/* #define USB_CFG_PULLUP_IOPORTNAME D */
+/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
+ * V+, you can connect and disconnect the device from firmware by calling
+ * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
+ * This constant defines the port on which the pullup resistor is connected.
+ */
+/* #define USB_CFG_PULLUP_BIT 4 */
+/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
+ * above) where the 1.5k pullup resistor is connected. See description
+ * above for details.
+ */
+
+/* --------------------------- Functional Range ---------------------------- */
+
+#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
+/* Define this to 1 if you want to compile a version with two endpoints: The
+ * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
+ * number).
+ */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT3 1
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 3 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP3_NUMBER 3
+/* If the so-called endpoint 3 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 3.
+ */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT4 1
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 4 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP4_NUMBER 4
+/* If the so-called endpoint 4 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 4.
+ */
+/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
+/* The above macro defines the startup condition for data toggling on the
+ * interrupt/bulk endpoints 1, 3 and 4. Defaults to USBPID_DATA1.
+ * Since the token is toggled BEFORE sending any data, the first packet is
+ * sent with the oposite value of this configuration!
+ */
+#define USB_CFG_IMPLEMENT_HALT 0
+/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
+ * for endpoint 1 (interrupt endpoint). Although you may not need this feature,
+ * it is required by the standard. We have made it a config option because it
+ * bloats the code considerably.
+ */
+#define USB_CFG_SUPPRESS_INTR_CODE 0
+/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
+ * want to send any data over them. If this macro is defined to 1, functions
+ * usbSetInterrupt(), usbSetInterrupt3() and usbSetInterrupt4() are omitted.
+ * This is useful if you need the interrupt-in endpoints in order to comply
+ * to an interface (e.g. HID), but never want to send any data. This option
+ * saves a couple of bytes in flash memory and the transmit buffers in RAM.
+ */
+#define USB_CFG_IS_SELF_POWERED 0
+/* Define this to 1 if the device has its own power supply. Set it to 0 if the
+ * device is powered from the USB bus.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITE 1
+/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
+ * transfers. Set it to 0 if you don't need it and want to save a couple of
+ * bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_READ 0
+/* Set this to 1 if you need to send control replies which are generated
+ * "on the fly" when usbFunctionRead() is called. If you only want to send
+ * data from a static buffer, set it to 0 and return the data from
+ * usbFunctionSetup(). This saves a couple of bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITEOUT 1
+/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
+ * You must implement the function usbFunctionWriteOut() which receives all
+ * interrupt/bulk data sent to any endpoint other than 0. The endpoint number
+ * can be found in 'usbRxToken'.
+ */
+#define USB_CFG_HAVE_FLOWCONTROL 0
+/* Define this to 1 if you want flowcontrol over USB data. See the definition
+ * of the macros usbDisableAllRequests() and usbEnableAllRequests() in
+ * usbdrv.h.
+ */
+#define USB_CFG_DRIVER_FLASH_PAGE 0
+/* If the device has more than 64 kBytes of flash, define this to the 64 k page
+ * where the driver's constants (descriptors) are located. Or in other words:
+ * Define this to 1 for boot loaders on the ATMega128.
+ */
+#define USB_CFG_LONG_TRANSFERS 0
+/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
+ * in a single control-in or control-out transfer. Note that the capability
+ * for long transfers increases the driver size.
+ */
+/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
+/* This macro is a hook if you want to do unconventional things. If it is
+ * defined, it's inserted at the beginning of received message processing.
+ * If you eat the received message and don't want default processing to
+ * proceed, do a return after doing your things. One possible application
+ * (besides debugging) is to flash a status LED on each packet.
+ */
+/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
+/* This macro is a hook if you need to know when an USB RESET occurs. It has
+ * one parameter which distinguishes between the start of RESET state and its
+ * end.
+ */
+/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
+/* This macro (if defined) is executed when a USB SET_ADDRESS request was
+ * received.
+ */
+#ifndef USB_COUNT_SOF
+#define USB_COUNT_SOF 1
+#endif
+/* define this macro to 1 if you need the global variable "usbSofCount" which
+ * counts SOF packets. This feature requires that the hardware interrupt is
+ * connected to D- instead of D+.
+ */
+/* #ifdef __ASSEMBLER__
+ * macro myAssemblerMacro
+ * in YL, TCNT0
+ * sts timer0Snapshot, YL
+ * endm
+ * #endif
+ * #define USB_SOF_HOOK myAssemblerMacro
+ * This macro (if defined) is executed in the assembler module when a
+ * Start Of Frame condition is detected. It is recommended to define it to
+ * the name of an assembler macro which is defined here as well so that more
+ * than one assembler instruction can be used. The macro may use the register
+ * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
+ * immediately after an SOF pulse may be lost and must be retried by the host.
+ * What can you do with this hook? Since the SOF signal occurs exactly every
+ * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
+ * designs running on the internal RC oscillator.
+ * Please note that Start Of Frame detection works only if D- is wired to the
+ * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
+ */
+#define USB_CFG_CHECK_DATA_TOGGLING 0
+/* define this macro to 1 if you want to filter out duplicate data packets
+ * sent by the host. Duplicates occur only as a consequence of communication
+ * errors, when the host does not receive an ACK. Please note that you need to
+ * implement the filtering yourself in usbFunctionWriteOut() and
+ * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
+ * for each control- and out-endpoint to check for duplicate packets.
+ */
+#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
+/* define this macro to 1 if you want the function usbMeasureFrameLength()
+ * compiled in. This function can be used to calibrate the AVR's RC oscillator.
+ */
+#define USB_USE_FAST_CRC 0
+/* The assembler module has two implementations for the CRC algorithm. One is
+ * faster, the other is smaller. This CRC routine is only used for transmitted
+ * messages where timing is not critical. The faster routine needs 31 cycles
+ * per byte while the smaller one needs 61 to 69 cycles. The faster routine
+ * may be worth the 32 bytes bigger code size if you transmit lots of data and
+ * run the AVR close to its limit.
+ */
+
+/* -------------------------- Device Description --------------------------- */
+
+#define USB_CFG_VENDOR_ID
+/* USB vendor ID for the device, low byte first. If you have registered your
+ * own Vendor ID, define it here. Otherwise you may use one of obdev's free
+ * shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_ID
+/* This is the ID of the product, low byte first. It is interpreted in the
+ * scope of the vendor ID. If you have registered your own VID with usb.org
+ * or if you have licensed a PID from somebody else, define it here. Otherwise
+ * you may use one of obdev's free shared VID/PID pairs. See the file
+ * USB-IDs-for-free.txt for details!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
+/* Define this to the length of the HID report descriptor, if you implement
+ * an HID device. Otherwise don't define it or define it to 0.
+ * If you use this define, you must add a PROGMEM character array named
+ * "usbHidReportDescriptor" to your code which contains the report descriptor.
+ * Don't forget to keep the array and this define in sync!
+ */
+
+/* #define USB_PUBLIC static */
+/* Use the define above if you #include usbdrv.c instead of linking against it.
+ * This technique saves a couple of bytes in flash memory.
+ */
+
+/* ------------------- Fine Control over USB Descriptors ------------------- */
+/* If you don't want to use the driver's default USB descriptors, you can
+ * provide our own. These can be provided as (1) fixed length static data in
+ * flash memory, (2) fixed length static data in RAM or (3) dynamically at
+ * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
+ * information about this function.
+ * Descriptor handling is configured through the descriptor's properties. If
+ * no properties are defined or if they are 0, the default descriptor is used.
+ * Possible properties are:
+ * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
+ * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
+ * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
+ * you want RAM pointers.
+ * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
+ * in static memory is in RAM, not in flash memory.
+ * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
+ * the driver must know the descriptor's length. The descriptor itself is
+ * found at the address of a well known identifier (see below).
+ * List of static descriptor names (must be declared PROGMEM if in flash):
+ * char usbDescriptorDevice[];
+ * char usbDescriptorConfiguration[];
+ * char usbDescriptorHidReport[];
+ * char usbDescriptorString0[];
+ * int usbDescriptorStringVendor[];
+ * int usbDescriptorStringDevice[];
+ * int usbDescriptorStringSerialNumber[];
+ * Other descriptors can't be provided statically, they must be provided
+ * dynamically at runtime.
+ *
+ * Descriptor properties are or-ed or added together, e.g.:
+ * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
+ *
+ * The following descriptors are defined:
+ * USB_CFG_DESCR_PROPS_DEVICE
+ * USB_CFG_DESCR_PROPS_CONFIGURATION
+ * USB_CFG_DESCR_PROPS_STRINGS
+ * USB_CFG_DESCR_PROPS_STRING_0
+ * USB_CFG_DESCR_PROPS_STRING_VENDOR
+ * USB_CFG_DESCR_PROPS_STRING_PRODUCT
+ * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
+ * USB_CFG_DESCR_PROPS_HID
+ * USB_CFG_DESCR_PROPS_HID_REPORT
+ * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
+ *
+ * Note about string descriptors: String descriptors are not just strings, they
+ * are Unicode strings prefixed with a 2 byte header. Example:
+ * int serialNumberDescriptor[] = {
+ * USB_STRING_DESCRIPTOR_HEADER(6),
+ * 'S', 'e', 'r', 'i', 'a', 'l'
+ * };
+ */
+
+#define USB_CFG_DESCR_PROPS_DEVICE USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_CONFIGURATION USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRINGS USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_0 USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_HID USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_HID_REPORT USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_UNKNOWN 0
+
+#define usbMsgPtr_t unsigned short
+/* If usbMsgPtr_t is not defined, it defaults to 'uchar *'. We define it to
+ * a scalar type here because gcc generates slightly shorter code for scalar
+ * arithmetics than for pointer arithmetics. Remove this define for backward
+ * type compatibility or define it to an 8 bit type if you use data in RAM only
+ * and all RAM is below 256 bytes (tiny memory model in IAR CC).
+ */
+
+/* ----------------------- Optional MCU Description ------------------------ */
+
+/* The following configurations have working defaults in usbdrv.h. You
+ * usually don't need to set them explicitly. Only if you want to run
+ * the driver on a device which is not yet supported or with a compiler
+ * which is not fully supported (such as IAR C) or if you use a differnt
+ * interrupt than INT0, you may have to define some of these.
+ */
+/* #define USB_INTR_CFG MCUCR */
+/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE GIMSK */
+/* #define USB_INTR_ENABLE_BIT INT0 */
+/* #define USB_INTR_PENDING GIFR */
+/* #define USB_INTR_PENDING_BIT INTF0 */
+/* #define USB_INTR_VECTOR INT0_vect */
+
+/* Set INT1 for D- falling edge to count SOF */
+/* #define USB_INTR_CFG EICRA */
+#ifndef USB_INTR_CFG_SET
+#define USB_INTR_CFG_SET ((1 << ISC11) | (0 << ISC10))
+#endif
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE EIMSK */
+#ifndef USB_INTR_ENABLE_BIT
+#define USB_INTR_ENABLE_BIT INT1
+#endif
+/* #define USB_INTR_PENDING EIFR */
+#ifndef USB_INTR_PENDING_BIT
+#define USB_INTR_PENDING_BIT INTF1
+#endif
+#ifndef USB_INTR_VECTOR
+#define USB_INTR_VECTOR INT1_vect
+#endif
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index 4a13ca5847..9362fbde78 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -296,7 +296,7 @@ static void send_consumer(uint16_t data) {
*------------------------------------------------------------------*/
static struct {
uint16_t len;
- enum { NONE, BOOTLOADER, SET_LED } kind;
+ enum { NONE, SET_LED } kind;
} last_req;
usbMsgLen_t usbFunctionSetup(uchar data[8]) {
@@ -323,11 +323,6 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
dprint("SET_LED:");
last_req.kind = SET_LED;
last_req.len = rq->wLength.word;
-#ifdef BOOTLOADER_SIZE
- } else if (rq->wValue.word == 0x0301) {
- last_req.kind = BOOTLOADER;
- last_req.len = rq->wLength.word;
-#endif
}
return USB_NO_MSG; // to get data in usbFunctionWrite
} else {
@@ -352,11 +347,6 @@ uchar usbFunctionWrite(uchar *data, uchar len) {
last_req.len = 0;
return 1;
break;
- case BOOTLOADER:
- usbDeviceDisconnect();
- bootloader_jump();
- return 1;
- break;
case NONE:
default:
return -1;
@@ -454,19 +444,15 @@ const PROGMEM uchar shared_hid_report[] = {
0x85, REPORT_ID_MOUSE, // Report ID
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
- // Buttons (5 bits)
+ // Buttons (8 bits)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button 1)
- 0x29, 0x05, // Usage Maximum (Button 5)
+ 0x29, 0x08, // Usage Maximum (Button 8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
- 0x95, 0x05, // Report Count (5)
+ 0x95, 0x08, // Report Count (8)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data, Variable, Absolute)
- // Button padding (3 bits)
- 0x95, 0x01, // Report Count (1)
- 0x75, 0x03, // Report Size (3)
- 0x81, 0x03, // Input (Constant)
// X/Y position (2 bytes)
0x05, 0x01, // Usage Page (Generic Desktop)
diff --git a/tmk_core/protocol/vusb/vusb.h b/tmk_core/protocol/vusb/vusb.h
index b4c73aabae..b1ecc98f37 100644
--- a/tmk_core/protocol/vusb/vusb.h
+++ b/tmk_core/protocol/vusb/vusb.h
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include "host_driver.h"
+#include <usbdrv/usbdrv.h>
typedef struct usbDescriptorHeader {
uchar bLength;
@@ -119,5 +120,7 @@ typedef struct usbConfigurationDescriptor {
#define USB_STRING_LEN(s) (sizeof(usbDescriptorHeader_t) + ((s) << 1))
+extern bool vusb_suspended;
+
host_driver_t *vusb_driver(void);
void vusb_transfer_keyboard(void);
diff --git a/tmk_core/protocol/xt.h b/tmk_core/protocol/xt.h
index 6dc5f19d00..538ff0e459 100644
--- a/tmk_core/protocol/xt.h
+++ b/tmk_core/protocol/xt.h
@@ -38,33 +38,36 @@ POSSIBILITY OF SUCH DAMAGE.
#pragma once
-#define XT_DATA_IN() \
- do { \
- XT_DATA_DDR &= ~(1 << XT_DATA_BIT); \
- XT_DATA_PORT |= (1 << XT_DATA_BIT); \
+#include "quantum.h"
+
+#define XT_DATA_IN() \
+ do { \
+ setPinInput(XT_DATA_PIN); \
+ writePinHigh(XT_DATA_PIN); \
} while (0)
-#define XT_DATA_READ() (XT_DATA_PIN & (1 << XT_DATA_BIT))
+#define XT_DATA_READ() readPin(XT_DATA_PIN)
-#define XT_DATA_LO() \
- do { \
- XT_DATA_PORT &= ~(1 << XT_DATA_BIT); \
- XT_DATA_DDR |= (1 << XT_DATA_BIT); \
+#define XT_DATA_LO() \
+ do { \
+ writePinLow(XT_DATA_PIN); \
+ setPinOutput(XT_DATA_PIN); \
} while (0)
-#define XT_CLOCK_IN() \
- do { \
- XT_CLOCK_DDR &= ~(1 << XT_CLOCK_BIT); \
- XT_CLOCK_PORT |= (1 << XT_CLOCK_BIT); \
+#define XT_CLOCK_IN() \
+ do { \
+ setPinInput(XT_CLOCK_PIN); \
+ writePinHigh(XT_CLOCK_PIN); \
} while (0)
-#define XT_CLOCK_READ() (XT_CLOCK_PIN & (1 << XT_CLOCK_BIT))
+#define XT_CLOCK_READ() readPin(XT_CLOCK_PIN)
-#define XT_CLOCK_LO() \
- do { \
- XT_CLOCK_PORT &= ~(1 << XT_CLOCK_BIT); \
- XT_CLOCK_DDR |= (1 << XT_CLOCK_BIT); \
+#define XT_CLOCK_LO() \
+ do { \
+ writePinLow(XT_CLOCK_PIN); \
+ setPinOutput(XT_CLOCK_PIN); \
} while (0)
-void xt_host_init(void);
+void xt_host_init(void);
+
uint8_t xt_host_recv(void);
diff --git a/tmk_core/protocol/xt_interrupt.c b/tmk_core/protocol/xt_interrupt.c
index 51e52243fd..ba9d71848f 100644
--- a/tmk_core/protocol/xt_interrupt.c
+++ b/tmk_core/protocol/xt_interrupt.c
@@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <stdbool.h>
#include <avr/interrupt.h>
-#include <util/delay.h>
#include "xt.h"
#include "wait.h"
#include "debug.h"
@@ -60,7 +59,7 @@ void xt_host_init(void) {
/* soft reset: pull clock line down for 20ms */
XT_DATA_LO();
XT_CLOCK_LO();
- _delay_ms(20);
+ wait_ms(20);
/* input mode with pullup */
XT_CLOCK_IN();
@@ -120,9 +119,10 @@ ISR(XT_INT_VECT) {
* Ring buffer to store scan codes from keyboard
*------------------------------------------------------------------*/
#define PBUF_SIZE 32
-static uint8_t pbuf[PBUF_SIZE];
-static uint8_t pbuf_head = 0;
-static uint8_t pbuf_tail = 0;
+static uint8_t pbuf[PBUF_SIZE];
+static uint8_t pbuf_head = 0;
+static uint8_t pbuf_tail = 0;
+
static inline void pbuf_enqueue(uint8_t data) {
uint8_t sreg = SREG;
cli();
@@ -135,6 +135,7 @@ static inline void pbuf_enqueue(uint8_t data) {
}
SREG = sreg;
}
+
static inline uint8_t pbuf_dequeue(void) {
uint8_t val = 0;
@@ -148,6 +149,7 @@ static inline uint8_t pbuf_dequeue(void) {
return val;
}
+
static inline bool pbuf_has_data(void) {
uint8_t sreg = SREG;
cli();
@@ -155,6 +157,7 @@ static inline bool pbuf_has_data(void) {
SREG = sreg;
return has_data;
}
+
static inline void pbuf_clear(void) {
uint8_t sreg = SREG;
cli();