mirror of
https://github.com/zsa/qmk_firmware.git
synced 2026-05-12 01:35:01 +00:00
Merge tag '0.18.16' into firmware22
This commit is contained in:
@@ -450,7 +450,7 @@ static void md_rgb_matrix_config_override(int i) {
|
||||
float bo = 0;
|
||||
float po;
|
||||
|
||||
uint8_t highest_active_layer = biton32(layer_state);
|
||||
uint8_t highest_active_layer = get_highest_layer(layer_state);
|
||||
|
||||
if (led_animation_circular) {
|
||||
// TODO: should use min/max values from LED configuration instead of
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "usb_main.h"
|
||||
|
||||
#include "host.h"
|
||||
#include "chibios_config.h"
|
||||
#include "debug.h"
|
||||
#include "suspend.h"
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
@@ -103,6 +104,13 @@ uint8_t extra_report_blank[3] = {0};
|
||||
* ---------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* USB Low Level driver specific endpoint fields */
|
||||
#if !defined(usb_lld_endpoint_fields)
|
||||
# define usb_lld_endpoint_fields \
|
||||
2, /* IN multiplier */ \
|
||||
NULL, /* SETUP buffer (not a SETUP endpoint) */
|
||||
#endif
|
||||
|
||||
/* HID specific constants */
|
||||
#define HID_GET_REPORT 0x01
|
||||
#define HID_GET_IDLE 0x02
|
||||
@@ -133,16 +141,15 @@ static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype
|
||||
static USBInEndpointState kbd_ep_state;
|
||||
/* keyboard endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
|
||||
static const USBEndpointConfig kbd_ep_config = {
|
||||
USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
|
||||
NULL, /* SETUP packet notification callback */
|
||||
kbd_in_cb, /* IN notification callback */
|
||||
NULL, /* OUT notification callback */
|
||||
KEYBOARD_EPSIZE, /* IN maximum packet size */
|
||||
0, /* OUT maximum packet size */
|
||||
&kbd_ep_state, /* IN Endpoint state */
|
||||
NULL, /* OUT endpoint state */
|
||||
2, /* IN multiplier */
|
||||
NULL /* SETUP buffer (not a SETUP endpoint) */
|
||||
USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
|
||||
NULL, /* SETUP packet notification callback */
|
||||
kbd_in_cb, /* IN notification callback */
|
||||
NULL, /* OUT notification callback */
|
||||
KEYBOARD_EPSIZE, /* IN maximum packet size */
|
||||
0, /* OUT maximum packet size */
|
||||
&kbd_ep_state, /* IN Endpoint state */
|
||||
NULL, /* OUT endpoint state */
|
||||
usb_lld_endpoint_fields /* USB driver specific endpoint fields */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -152,16 +159,15 @@ static USBInEndpointState mouse_ep_state;
|
||||
|
||||
/* mouse endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
|
||||
static const USBEndpointConfig mouse_ep_config = {
|
||||
USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
|
||||
NULL, /* SETUP packet notification callback */
|
||||
mouse_in_cb, /* IN notification callback */
|
||||
NULL, /* OUT notification callback */
|
||||
MOUSE_EPSIZE, /* IN maximum packet size */
|
||||
0, /* OUT maximum packet size */
|
||||
&mouse_ep_state, /* IN Endpoint state */
|
||||
NULL, /* OUT endpoint state */
|
||||
2, /* IN multiplier */
|
||||
NULL /* SETUP buffer (not a SETUP endpoint) */
|
||||
USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
|
||||
NULL, /* SETUP packet notification callback */
|
||||
mouse_in_cb, /* IN notification callback */
|
||||
NULL, /* OUT notification callback */
|
||||
MOUSE_EPSIZE, /* IN maximum packet size */
|
||||
0, /* OUT maximum packet size */
|
||||
&mouse_ep_state, /* IN Endpoint state */
|
||||
NULL, /* OUT endpoint state */
|
||||
usb_lld_endpoint_fields /* USB driver specific endpoint fields */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -171,36 +177,19 @@ static USBInEndpointState shared_ep_state;
|
||||
|
||||
/* shared endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
|
||||
static const USBEndpointConfig shared_ep_config = {
|
||||
USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
|
||||
NULL, /* SETUP packet notification callback */
|
||||
shared_in_cb, /* IN notification callback */
|
||||
NULL, /* OUT notification callback */
|
||||
SHARED_EPSIZE, /* IN maximum packet size */
|
||||
0, /* OUT maximum packet size */
|
||||
&shared_ep_state, /* IN Endpoint state */
|
||||
NULL, /* OUT endpoint state */
|
||||
2, /* IN multiplier */
|
||||
NULL /* SETUP buffer (not a SETUP endpoint) */
|
||||
USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
|
||||
NULL, /* SETUP packet notification callback */
|
||||
shared_in_cb, /* IN notification callback */
|
||||
NULL, /* OUT notification callback */
|
||||
SHARED_EPSIZE, /* IN maximum packet size */
|
||||
0, /* OUT maximum packet size */
|
||||
&shared_ep_state, /* IN Endpoint state */
|
||||
NULL, /* OUT endpoint state */
|
||||
usb_lld_endpoint_fields /* USB driver specific endpoint fields */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef WEBUSB_ENABLE
|
||||
/** Microsoft OS 2.0 Descriptor. This is used by Windows to select the USB driver for the device.
|
||||
*
|
||||
* For WebUSB in Chrome, the correct driver is WinUSB, which is selected via CompatibleID.
|
||||
*
|
||||
* Additionally, while Chrome is built using libusb, a magic registry key needs to be set containing a GUID for
|
||||
* the device.
|
||||
*/
|
||||
const MS_OS_20_Descriptor_t PROGMEM MS_OS_20_Descriptor = MS_OS_20_DESCRIPTOR;
|
||||
|
||||
/** URL descriptor string. This is a UTF-8 string containing a URL excluding the prefix. At least one of these must be
|
||||
* defined and returned when the Landing Page descriptor index is requested.
|
||||
*/
|
||||
const WebUSB_URL_Descriptor_t PROGMEM WebUSB_LandingPage = WEBUSB_URL_DESCRIPTOR(WEBUSB_LANDING_PAGE_URL);
|
||||
#endif
|
||||
|
||||
#if STM32_USB_USE_OTG1
|
||||
#ifdef USB_ENDPOINTS_ARE_REORDERABLE
|
||||
typedef struct {
|
||||
size_t queue_capacity_in;
|
||||
size_t queue_capacity_out;
|
||||
@@ -227,23 +216,22 @@ typedef struct {
|
||||
} usb_driver_config_t;
|
||||
#endif
|
||||
|
||||
#if STM32_USB_USE_OTG1
|
||||
#ifdef USB_ENDPOINTS_ARE_REORDERABLE
|
||||
/* Reusable initialization structure - see USBEndpointConfig comment at top of file */
|
||||
# define QMK_USB_DRIVER_CONFIG(stream, notification, fixedsize) \
|
||||
{ \
|
||||
.queue_capacity_in = stream##_IN_CAPACITY, .queue_capacity_out = stream##_OUT_CAPACITY, \
|
||||
.inout_ep_config = \
|
||||
{ \
|
||||
stream##_IN_MODE, /* Interrupt EP */ \
|
||||
NULL, /* SETUP packet notification callback */ \
|
||||
qmkusbDataTransmitted, /* IN notification callback */ \
|
||||
qmkusbDataReceived, /* OUT notification callback */ \
|
||||
stream##_EPSIZE, /* IN maximum packet size */ \
|
||||
stream##_EPSIZE, /* OUT maximum packet size */ \
|
||||
NULL, /* IN Endpoint state */ \
|
||||
NULL, /* OUT endpoint state */ \
|
||||
2, /* IN multiplier */ \
|
||||
NULL /* SETUP buffer (not a SETUP endpoint) */ \
|
||||
stream##_IN_MODE, /* Interrupt EP */ \
|
||||
NULL, /* SETUP packet notification callback */ \
|
||||
qmkusbDataTransmitted, /* IN notification callback */ \
|
||||
qmkusbDataReceived, /* OUT notification callback */ \
|
||||
stream##_EPSIZE, /* IN maximum packet size */ \
|
||||
stream##_EPSIZE, /* OUT maximum packet size */ \
|
||||
NULL, /* IN Endpoint state */ \
|
||||
NULL, /* OUT endpoint state */ \
|
||||
usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
|
||||
}, \
|
||||
.int_ep_config = \
|
||||
{ \
|
||||
@@ -255,8 +243,7 @@ typedef struct {
|
||||
0, /* OUT maximum packet size */ \
|
||||
NULL, /* IN Endpoint state */ \
|
||||
NULL, /* OUT endpoint state */ \
|
||||
2, /* IN multiplier */ \
|
||||
NULL, /* SETUP buffer (not a SETUP endpoint) */ \
|
||||
usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
|
||||
}, \
|
||||
.config = { \
|
||||
.usbp = &USB_DRIVER, \
|
||||
@@ -279,29 +266,27 @@ typedef struct {
|
||||
.queue_capacity_in = stream##_IN_CAPACITY, .queue_capacity_out = stream##_OUT_CAPACITY, \
|
||||
.in_ep_config = \
|
||||
{ \
|
||||
stream##_IN_MODE, /* Interrupt EP */ \
|
||||
NULL, /* SETUP packet notification callback */ \
|
||||
qmkusbDataTransmitted, /* IN notification callback */ \
|
||||
NULL, /* OUT notification callback */ \
|
||||
stream##_EPSIZE, /* IN maximum packet size */ \
|
||||
0, /* OUT maximum packet size */ \
|
||||
NULL, /* IN Endpoint state */ \
|
||||
NULL, /* OUT endpoint state */ \
|
||||
2, /* IN multiplier */ \
|
||||
NULL /* SETUP buffer (not a SETUP endpoint) */ \
|
||||
stream##_IN_MODE, /* Interrupt EP */ \
|
||||
NULL, /* SETUP packet notification callback */ \
|
||||
qmkusbDataTransmitted, /* IN notification callback */ \
|
||||
NULL, /* OUT notification callback */ \
|
||||
stream##_EPSIZE, /* IN maximum packet size */ \
|
||||
0, /* OUT maximum packet size */ \
|
||||
NULL, /* IN Endpoint state */ \
|
||||
NULL, /* OUT endpoint state */ \
|
||||
usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
|
||||
}, \
|
||||
.out_ep_config = \
|
||||
{ \
|
||||
stream##_OUT_MODE, /* Interrupt EP */ \
|
||||
NULL, /* SETUP packet notification callback */ \
|
||||
NULL, /* IN notification callback */ \
|
||||
qmkusbDataReceived, /* OUT notification callback */ \
|
||||
0, /* IN maximum packet size */ \
|
||||
stream##_EPSIZE, /* OUT maximum packet size */ \
|
||||
NULL, /* IN Endpoint state */ \
|
||||
NULL, /* OUT endpoint state */ \
|
||||
2, /* IN multiplier */ \
|
||||
NULL, /* SETUP buffer (not a SETUP endpoint) */ \
|
||||
stream##_OUT_MODE, /* Interrupt EP */ \
|
||||
NULL, /* SETUP packet notification callback */ \
|
||||
NULL, /* IN notification callback */ \
|
||||
qmkusbDataReceived, /* OUT notification callback */ \
|
||||
0, /* IN maximum packet size */ \
|
||||
stream##_EPSIZE, /* OUT maximum packet size */ \
|
||||
NULL, /* IN Endpoint state */ \
|
||||
NULL, /* OUT endpoint state */ \
|
||||
usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
|
||||
}, \
|
||||
.int_ep_config = \
|
||||
{ \
|
||||
@@ -313,8 +298,7 @@ typedef struct {
|
||||
0, /* OUT maximum packet size */ \
|
||||
NULL, /* IN Endpoint state */ \
|
||||
NULL, /* OUT endpoint state */ \
|
||||
2, /* IN multiplier */ \
|
||||
NULL, /* SETUP buffer (not a SETUP endpoint) */ \
|
||||
usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
|
||||
}, \
|
||||
.config = { \
|
||||
.usbp = &USB_DRIVER, \
|
||||
@@ -526,7 +510,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
|
||||
usbInitEndpointI(usbp, SHARED_IN_EPNUM, &shared_ep_config);
|
||||
#endif
|
||||
for (int i = 0; i < NUM_USB_DRIVERS; i++) {
|
||||
#if STM32_USB_USE_OTG1
|
||||
#ifdef USB_ENDPOINTS_ARE_REORDERABLE
|
||||
usbInitEndpointI(usbp, drivers.array[i].config.bulk_in, &drivers.array[i].inout_ep_config);
|
||||
#else
|
||||
usbInitEndpointI(usbp, drivers.array[i].config.bulk_in, &drivers.array[i].in_ep_config);
|
||||
@@ -774,7 +758,7 @@ static const USBConfig usbcfg = {
|
||||
*/
|
||||
void init_usb_driver(USBDriver *usbp) {
|
||||
for (int i = 0; i < NUM_USB_DRIVERS; i++) {
|
||||
#if STM32_USB_USE_OTG1
|
||||
#ifdef USB_ENDPOINTS_ARE_REORDERABLE
|
||||
QMKUSBDriver *driver = &drivers.array[i].driver;
|
||||
drivers.array[i].inout_ep_config.in_state = &drivers.array[i].in_ep_state;
|
||||
drivers.array[i].inout_ep_config.out_state = &drivers.array[i].out_ep_state;
|
||||
|
||||
@@ -93,6 +93,11 @@ void host_mouse_send(report_mouse_t *report) {
|
||||
if (!driver) return;
|
||||
#ifdef MOUSE_SHARED_EP
|
||||
report->report_id = REPORT_ID_MOUSE;
|
||||
#endif
|
||||
#ifdef MOUSE_EXTENDED_REPORT
|
||||
// clip and copy to Boot protocol XY
|
||||
report->boot_x = (report->x > 127) ? 127 : ((report->x < -127) ? -127 : report->x);
|
||||
report->boot_y = (report->y > 127) ? 127 : ((report->y < -127) ? -127 : report->y);
|
||||
#endif
|
||||
(*driver->send_mouse)(report);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
#include "midi.h"
|
||||
#include <string.h> //for memcpy
|
||||
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#ifndef MIN
|
||||
# define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL 0
|
||||
|
||||
@@ -201,15 +201,25 @@ typedef struct {
|
||||
uint32_t usage;
|
||||
} __attribute__((packed)) report_programmable_button_t;
|
||||
|
||||
#ifdef MOUSE_EXTENDED_REPORT
|
||||
typedef int16_t mouse_xy_report_t;
|
||||
#else
|
||||
typedef int8_t mouse_xy_report_t;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
#ifdef MOUSE_SHARED_EP
|
||||
uint8_t report_id;
|
||||
#endif
|
||||
uint8_t buttons;
|
||||
int8_t x;
|
||||
int8_t y;
|
||||
int8_t v;
|
||||
int8_t h;
|
||||
#ifdef MOUSE_EXTENDED_REPORT
|
||||
int8_t boot_x;
|
||||
int8_t boot_y;
|
||||
#endif
|
||||
mouse_xy_report_t x;
|
||||
mouse_xy_report_t y;
|
||||
int8_t v;
|
||||
int8_t h;
|
||||
} __attribute__((packed)) report_mouse_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 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,
|
||||
GPL-compatible, and OK to use in both free and proprietary applications.
|
||||
Additions and corrections to this file are welcome.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define SERIAL_UART_DATA UDR1
|
||||
|
||||
/* host role */
|
||||
void serial_init(void);
|
||||
uint8_t serial_recv(void);
|
||||
int16_t serial_recv2(void);
|
||||
void serial_send(uint8_t data);
|
||||
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 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,
|
||||
GPL-compatible, and OK to use in both free and proprietary applications.
|
||||
Additions and corrections to this file are welcome.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "serial.h"
|
||||
|
||||
/*
|
||||
* Stupid Inefficient Busy-wait Software Serial
|
||||
* which is still useful for negative logic signal like Sun protocol
|
||||
* if it is not supported by hardware UART.
|
||||
*
|
||||
* TODO: delay is not accurate enough. Instruction cycle should be counted and inline assemby is needed.
|
||||
*/
|
||||
|
||||
#define WAIT_US (1000000L / SERIAL_SOFT_BAUD)
|
||||
|
||||
#ifdef SERIAL_SOFT_LOGIC_NEGATIVE
|
||||
# define SERIAL_SOFT_RXD_IN() !(SERIAL_SOFT_RXD_READ())
|
||||
# define SERIAL_SOFT_TXD_ON() SERIAL_SOFT_TXD_LO()
|
||||
# define SERIAL_SOFT_TXD_OFF() SERIAL_SOFT_TXD_HI()
|
||||
#else
|
||||
# define SERIAL_SOFT_RXD_IN() !!(SERIAL_SOFT_RXD_READ())
|
||||
# define SERIAL_SOFT_TXD_ON() SERIAL_SOFT_TXD_HI()
|
||||
# define SERIAL_SOFT_TXD_OFF() SERIAL_SOFT_TXD_LO()
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_SOFT_PARITY_EVEN
|
||||
# define SERIAL_SOFT_PARITY_VAL 0
|
||||
#elif defined(SERIAL_SOFT_PARITY_ODD)
|
||||
# define SERIAL_SOFT_PARITY_VAL 1
|
||||
#endif
|
||||
|
||||
/* debug for signal timing, see debug pin with oscilloscope */
|
||||
#ifdef SERIAL_SOFT_DEBUG
|
||||
# define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1 << 7)
|
||||
# define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1 << 7)
|
||||
#else
|
||||
# define SERIAL_SOFT_DEBUG_INIT()
|
||||
# define SERIAL_SOFT_DEBUG_TGL()
|
||||
#endif
|
||||
|
||||
void serial_init(void) {
|
||||
SERIAL_SOFT_DEBUG_INIT();
|
||||
|
||||
SERIAL_SOFT_RXD_INIT();
|
||||
SERIAL_SOFT_TXD_INIT();
|
||||
}
|
||||
|
||||
/* RX ring buffer */
|
||||
#define RBUF_SIZE 8
|
||||
static uint8_t rbuf[RBUF_SIZE];
|
||||
static uint8_t rbuf_head = 0;
|
||||
static uint8_t rbuf_tail = 0;
|
||||
|
||||
uint8_t serial_recv(void) {
|
||||
uint8_t data = 0;
|
||||
if (rbuf_head == rbuf_tail) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
data = rbuf[rbuf_tail];
|
||||
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
|
||||
return data;
|
||||
}
|
||||
|
||||
int16_t serial_recv2(void) {
|
||||
uint8_t data = 0;
|
||||
if (rbuf_head == rbuf_tail) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data = rbuf[rbuf_tail];
|
||||
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
|
||||
return data;
|
||||
}
|
||||
|
||||
void serial_send(uint8_t data) {
|
||||
/* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */
|
||||
|
||||
#ifdef SERIAL_SOFT_BIT_ORDER_MSB
|
||||
# ifdef SERIAL_SOFT_DATA_7BIT
|
||||
uint8_t mask = 0x40;
|
||||
# else
|
||||
uint8_t mask = 0x80;
|
||||
# endif
|
||||
#else
|
||||
uint8_t mask = 0x01;
|
||||
#endif
|
||||
|
||||
uint8_t parity = 0;
|
||||
|
||||
/* start bit */
|
||||
SERIAL_SOFT_TXD_OFF();
|
||||
_delay_us(WAIT_US);
|
||||
|
||||
#ifdef SERIAL_SOFT_DATA_7BIT
|
||||
while (mask & 0x7F) {
|
||||
#else
|
||||
while (mask & 0xFF) {
|
||||
#endif
|
||||
if (data & mask) {
|
||||
SERIAL_SOFT_TXD_ON();
|
||||
parity ^= 1;
|
||||
} else {
|
||||
SERIAL_SOFT_TXD_OFF();
|
||||
}
|
||||
_delay_us(WAIT_US);
|
||||
|
||||
#ifdef SERIAL_SOFT_BIT_ORDER_MSB
|
||||
mask >>= 1;
|
||||
#else
|
||||
mask <<= 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD)
|
||||
/* to center of parity bit */
|
||||
if (parity != SERIAL_SOFT_PARITY_VAL) {
|
||||
SERIAL_SOFT_TXD_ON();
|
||||
} else {
|
||||
SERIAL_SOFT_TXD_OFF();
|
||||
}
|
||||
_delay_us(WAIT_US);
|
||||
#endif
|
||||
|
||||
/* stop bit */
|
||||
SERIAL_SOFT_TXD_ON();
|
||||
_delay_us(WAIT_US);
|
||||
}
|
||||
|
||||
/* detect edge of start bit */
|
||||
ISR(SERIAL_SOFT_RXD_VECT) {
|
||||
SERIAL_SOFT_DEBUG_TGL();
|
||||
SERIAL_SOFT_RXD_INT_ENTER();
|
||||
|
||||
uint8_t data = 0;
|
||||
|
||||
#ifdef SERIAL_SOFT_BIT_ORDER_MSB
|
||||
# ifdef SERIAL_SOFT_DATA_7BIT
|
||||
uint8_t mask = 0x40;
|
||||
# else
|
||||
uint8_t mask = 0x80;
|
||||
# endif
|
||||
#else
|
||||
uint8_t mask = 0x01;
|
||||
#endif
|
||||
|
||||
uint8_t parity = 0;
|
||||
|
||||
/* to center of start bit */
|
||||
_delay_us(WAIT_US / 2);
|
||||
SERIAL_SOFT_DEBUG_TGL();
|
||||
do {
|
||||
/* to center of next bit */
|
||||
_delay_us(WAIT_US);
|
||||
|
||||
SERIAL_SOFT_DEBUG_TGL();
|
||||
if (SERIAL_SOFT_RXD_IN()) {
|
||||
data |= mask;
|
||||
parity ^= 1;
|
||||
}
|
||||
#ifdef SERIAL_SOFT_BIT_ORDER_MSB
|
||||
mask >>= 1;
|
||||
#else
|
||||
mask <<= 1;
|
||||
#endif
|
||||
#ifdef SERIAL_SOFT_DATA_7BIT
|
||||
} while (mask & 0x7F);
|
||||
#else
|
||||
} while (mask & 0xFF);
|
||||
#endif
|
||||
|
||||
#if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD)
|
||||
/* to center of parity bit */
|
||||
_delay_us(WAIT_US);
|
||||
if (SERIAL_SOFT_RXD_IN()) {
|
||||
parity ^= 1;
|
||||
}
|
||||
SERIAL_SOFT_DEBUG_TGL();
|
||||
#endif
|
||||
|
||||
/* to center of stop bit */
|
||||
_delay_us(WAIT_US);
|
||||
|
||||
uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
|
||||
#if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD)
|
||||
if ((parity == SERIAL_SOFT_PARITY_VAL) && next != rbuf_tail) {
|
||||
#else
|
||||
if (next != rbuf_tail) {
|
||||
#endif
|
||||
rbuf[rbuf_head] = data;
|
||||
rbuf_head = next;
|
||||
}
|
||||
|
||||
SERIAL_SOFT_RXD_INT_EXIT();
|
||||
SERIAL_SOFT_DEBUG_TGL();
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
Copyright 2013 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,
|
||||
GPL-compatible, and OK to use in both free and proprietary applications.
|
||||
Additions and corrections to this file are welcome.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#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)
|
||||
// Last 1 space: RBUF_SPACE == 2
|
||||
// Full: RBUF_SPACE == 1(last cell of rbuf be never used.)
|
||||
# define RBUF_SPACE() (rbuf_head < rbuf_tail ? (rbuf_tail - rbuf_head) : (RBUF_SIZE - rbuf_head + rbuf_tail))
|
||||
// allow to send
|
||||
# define rbuf_check_rts_lo() \
|
||||
do { \
|
||||
if (RBUF_SPACE() > 2) SERIAL_UART_RTS_LO(); \
|
||||
} while (0)
|
||||
// prohibit to send
|
||||
# define rbuf_check_rts_hi() \
|
||||
do { \
|
||||
if (RBUF_SPACE() <= 2) SERIAL_UART_RTS_HI(); \
|
||||
} while (0)
|
||||
#else
|
||||
# define rbuf_check_rts_lo()
|
||||
# define rbuf_check_rts_hi()
|
||||
#endif
|
||||
|
||||
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
|
||||
static uint8_t rbuf[RBUF_SIZE];
|
||||
static uint8_t rbuf_head = 0;
|
||||
static uint8_t rbuf_tail = 0;
|
||||
|
||||
uint8_t serial_recv(void) {
|
||||
uint8_t data = 0;
|
||||
if (rbuf_head == rbuf_tail) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
data = rbuf[rbuf_tail];
|
||||
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
|
||||
rbuf_check_rts_lo();
|
||||
return data;
|
||||
}
|
||||
|
||||
int16_t serial_recv2(void) {
|
||||
uint8_t data = 0;
|
||||
if (rbuf_head == rbuf_tail) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data = rbuf[rbuf_tail];
|
||||
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
|
||||
rbuf_check_rts_lo();
|
||||
return data;
|
||||
}
|
||||
|
||||
void serial_send(uint8_t data) {
|
||||
while (!SERIAL_UART_TXD_READY)
|
||||
;
|
||||
SERIAL_UART_DATA = data;
|
||||
}
|
||||
|
||||
// USART RX complete interrupt
|
||||
ISR(SERIAL_UART_RXD_VECT) {
|
||||
uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
|
||||
if (next != rbuf_tail) {
|
||||
rbuf[rbuf_head] = SERIAL_UART_DATA;
|
||||
rbuf_head = next;
|
||||
}
|
||||
rbuf_check_rts_hi();
|
||||
}
|
||||
@@ -48,6 +48,9 @@
|
||||
# include "joystick.h"
|
||||
#endif
|
||||
|
||||
// TODO: wb32 support defines ISO macro which breaks PRODUCT stringification
|
||||
#undef ISO
|
||||
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
@@ -129,14 +132,27 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
|
||||
HID_RI_REPORT_SIZE(8, 0x01),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||
|
||||
// X/Y position (2 bytes)
|
||||
# ifdef MOUSE_EXTENDED_REPORT
|
||||
// Boot protocol XY ignored in Report protocol
|
||||
HID_RI_REPORT_COUNT(8, 0x02),
|
||||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
HID_RI_INPUT(8, HID_IOF_CONSTANT),
|
||||
# endif
|
||||
// X/Y position (2 or 4 bytes)
|
||||
HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
|
||||
HID_RI_USAGE(8, 0x30), // X
|
||||
HID_RI_USAGE(8, 0x31), // Y
|
||||
# ifndef MOUSE_EXTENDED_REPORT
|
||||
HID_RI_LOGICAL_MINIMUM(8, -127),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 127),
|
||||
HID_RI_REPORT_COUNT(8, 0x02),
|
||||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
# else
|
||||
HID_RI_LOGICAL_MINIMUM(16, -32767),
|
||||
HID_RI_LOGICAL_MAXIMUM(16, 32767),
|
||||
HID_RI_REPORT_COUNT(8, 0x02),
|
||||
HID_RI_REPORT_SIZE(8, 0x10),
|
||||
# endif
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
|
||||
|
||||
// Vertical wheel (1 byte)
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
|
||||
#ifdef PROTOCOL_CHIBIOS
|
||||
# include <hal.h>
|
||||
# if STM32_USB_USE_OTG1 == TRUE
|
||||
# define USB_ENDPOINTS_ARE_REORDERABLE
|
||||
# endif
|
||||
#endif
|
||||
#ifdef WEBUSB_ENABLE
|
||||
# include "webusb_descriptor.h"
|
||||
@@ -229,7 +232,7 @@ enum usb_endpoints {
|
||||
|
||||
#ifdef RAW_ENABLE
|
||||
RAW_IN_EPNUM = NEXT_EPNUM,
|
||||
# if STM32_USB_USE_OTG1
|
||||
# ifdef USB_ENDPOINTS_ARE_REORDERABLE
|
||||
# define RAW_OUT_EPNUM RAW_IN_EPNUM
|
||||
# else
|
||||
RAW_OUT_EPNUM = NEXT_EPNUM,
|
||||
@@ -247,7 +250,7 @@ enum usb_endpoints {
|
||||
// ChibiOS has enough memory and descriptor to actually enable the endpoint
|
||||
// It could use the same endpoint numbers, as that's supported by ChibiOS
|
||||
// But the QMK code currently assumes that the endpoint numbers are different
|
||||
# if STM32_USB_USE_OTG1
|
||||
# ifdef USB_ENDPOINTS_ARE_REORDERABLE
|
||||
# define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM
|
||||
# else
|
||||
CONSOLE_OUT_EPNUM = NEXT_EPNUM,
|
||||
@@ -259,7 +262,7 @@ enum usb_endpoints {
|
||||
|
||||
#ifdef MIDI_ENABLE
|
||||
MIDI_STREAM_IN_EPNUM = NEXT_EPNUM,
|
||||
# if STM32_USB_USE_OTG1
|
||||
# ifdef USB_ENDPOINTS_ARE_REORDERABLE
|
||||
# define MIDI_STREAM_OUT_EPNUM MIDI_STREAM_IN_EPNUM
|
||||
# else
|
||||
MIDI_STREAM_OUT_EPNUM = NEXT_EPNUM,
|
||||
@@ -269,7 +272,7 @@ enum usb_endpoints {
|
||||
#ifdef VIRTSER_ENABLE
|
||||
CDC_NOTIFICATION_EPNUM = NEXT_EPNUM,
|
||||
CDC_IN_EPNUM = NEXT_EPNUM,
|
||||
# if STM32_USB_USE_OTG1
|
||||
# ifdef USB_ENDPOINTS_ARE_REORDERABLE
|
||||
# define CDC_OUT_EPNUM CDC_IN_EPNUM
|
||||
# else
|
||||
CDC_OUT_EPNUM = NEXT_EPNUM,
|
||||
@@ -285,7 +288,7 @@ enum usb_endpoints {
|
||||
|
||||
#ifdef JOYSTICK_ENABLE
|
||||
JOYSTICK_IN_EPNUM = NEXT_EPNUM,
|
||||
# if STM32_USB_USE_OTG1
|
||||
# ifdef USB_ENDPOINTS_ARE_REORDERABLE
|
||||
JOYSTICK_OUT_EPNUM = JOYSTICK_IN_EPNUM,
|
||||
# else
|
||||
JOYSTICK_OUT_EPNUM = NEXT_EPNUM,
|
||||
@@ -295,7 +298,7 @@ enum usb_endpoints {
|
||||
#ifdef DIGITIZER_ENABLE
|
||||
# if !defined(DIGITIZER_SHARED_EP)
|
||||
DIGITIZER_IN_EPNUM = NEXT_EPNUM,
|
||||
# if STM32_USB_USE_OTG1
|
||||
# ifdef USB_ENDPOINTS_ARE_REORDERABLE
|
||||
DIGITIZER_OUT_EPNUM = DIGITIZER_IN_EPNUM,
|
||||
# else
|
||||
DIGITIZER_OUT_EPNUM = NEXT_EPNUM,
|
||||
|
||||
@@ -482,14 +482,28 @@ const PROGMEM uchar shared_hid_report[] = {
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x81, 0x02, // Input (Data, Variable, Absolute)
|
||||
|
||||
// X/Y position (2 bytes)
|
||||
# ifdef MOUSE_EXTENDED_REPORT
|
||||
// Boot protocol XY ignored in Report protocol
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x81, 0x03, // Input (Constant)
|
||||
# endif
|
||||
|
||||
// X/Y position (2 or 4 bytes)
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
0x09, 0x30, // Usage (X)
|
||||
0x09, 0x31, // Usage (Y)
|
||||
# ifndef MOUSE_EXTENDED_REPORT
|
||||
0x15, 0x81, // Logical Minimum (-127)
|
||||
0x25, 0x7F, // Logical Maximum (127)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
# else
|
||||
0x16, 0x01, 0x80, // Logical Minimum (-32767)
|
||||
0x26, 0xFF, 0x7F, // Logical Maximum (32767)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x75, 0x10, // Report Size (16)
|
||||
# endif
|
||||
0x81, 0x06, // Input (Data, Variable, Relative)
|
||||
|
||||
// Vertical wheel (1 byte)
|
||||
|
||||
Reference in New Issue
Block a user