clang-format changes
This commit is contained in:
parent
61af76a10d
commit
b624f32f94
502 changed files with 32259 additions and 39062 deletions
|
@ -30,24 +30,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "transport.h"
|
||||
|
||||
#ifdef ENCODER_ENABLE
|
||||
#include "encoder.h"
|
||||
# include "encoder.h"
|
||||
#endif
|
||||
|
||||
#if (MATRIX_COLS <= 8)
|
||||
# define print_matrix_header() print("\nr/c 01234567\n")
|
||||
# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
|
||||
# define matrix_bitpop(i) bitpop(matrix[i])
|
||||
# define ROW_SHIFTER ((uint8_t)1)
|
||||
# define print_matrix_header() print("\nr/c 01234567\n")
|
||||
# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
|
||||
# define matrix_bitpop(i) bitpop(matrix[i])
|
||||
# define ROW_SHIFTER ((uint8_t)1)
|
||||
#elif (MATRIX_COLS <= 16)
|
||||
# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
|
||||
# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
|
||||
# define matrix_bitpop(i) bitpop16(matrix[i])
|
||||
# define ROW_SHIFTER ((uint16_t)1)
|
||||
# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
|
||||
# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
|
||||
# define matrix_bitpop(i) bitpop16(matrix[i])
|
||||
# define ROW_SHIFTER ((uint16_t)1)
|
||||
#elif (MATRIX_COLS <= 32)
|
||||
# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
|
||||
# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
|
||||
# define matrix_bitpop(i) bitpop32(matrix[i])
|
||||
# define ROW_SHIFTER ((uint32_t)1)
|
||||
# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
|
||||
# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
|
||||
# define matrix_bitpop(i) bitpop32(matrix[i])
|
||||
# define ROW_SHIFTER ((uint32_t)1)
|
||||
#endif
|
||||
|
||||
#define ERROR_DISCONNECT_COUNT 5
|
||||
|
@ -87,8 +87,8 @@ inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
|
|||
inline uint8_t matrix_cols(void) { return MATRIX_COLS; }
|
||||
|
||||
bool matrix_is_modified(void) {
|
||||
if (debounce_active()) return false;
|
||||
return true;
|
||||
if (debounce_active()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
|
||||
|
@ -96,22 +96,22 @@ inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((mat
|
|||
inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; }
|
||||
|
||||
void matrix_print(void) {
|
||||
print_matrix_header();
|
||||
print_matrix_header();
|
||||
|
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||
phex(row);
|
||||
print(": ");
|
||||
print_matrix_row(row);
|
||||
print("\n");
|
||||
}
|
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||
phex(row);
|
||||
print(": ");
|
||||
print_matrix_row(row);
|
||||
print("\n");
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t matrix_key_count(void) {
|
||||
uint8_t count = 0;
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
count += matrix_bitpop(i);
|
||||
}
|
||||
return count;
|
||||
uint8_t count = 0;
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
count += matrix_bitpop(i);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// matrix code
|
||||
|
@ -119,224 +119,224 @@ uint8_t matrix_key_count(void) {
|
|||
#ifdef DIRECT_PINS
|
||||
|
||||
static void init_pins(void) {
|
||||
for (int row = 0; row < MATRIX_ROWS; row++) {
|
||||
for (int col = 0; col < MATRIX_COLS; col++) {
|
||||
pin_t pin = direct_pins[row][col];
|
||||
if (pin != NO_PIN) {
|
||||
setPinInputHigh(pin);
|
||||
}
|
||||
for (int row = 0; row < MATRIX_ROWS; row++) {
|
||||
for (int col = 0; col < MATRIX_COLS; col++) {
|
||||
pin_t pin = direct_pins[row][col];
|
||||
if (pin != NO_PIN) {
|
||||
setPinInputHigh(pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
|
||||
matrix_row_t last_row_value = current_matrix[current_row];
|
||||
current_matrix[current_row] = 0;
|
||||
matrix_row_t last_row_value = current_matrix[current_row];
|
||||
current_matrix[current_row] = 0;
|
||||
|
||||
for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
|
||||
pin_t pin = direct_pins[current_row][col_index];
|
||||
if (pin != NO_PIN) {
|
||||
current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index);
|
||||
for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
|
||||
pin_t pin = direct_pins[current_row][col_index];
|
||||
if (pin != NO_PIN) {
|
||||
current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (last_row_value != current_matrix[current_row]);
|
||||
return (last_row_value != current_matrix[current_row]);
|
||||
}
|
||||
|
||||
#elif (DIODE_DIRECTION == COL2ROW)
|
||||
|
||||
static void select_row(uint8_t row) {
|
||||
setPinOutput(row_pins[row]);
|
||||
writePinLow(row_pins[row]);
|
||||
setPinOutput(row_pins[row]);
|
||||
writePinLow(row_pins[row]);
|
||||
}
|
||||
|
||||
static void unselect_row(uint8_t row) { setPinInputHigh(row_pins[row]); }
|
||||
|
||||
static void unselect_rows(void) {
|
||||
for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
|
||||
setPinInputHigh(row_pins[x]);
|
||||
}
|
||||
for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
|
||||
setPinInputHigh(row_pins[x]);
|
||||
}
|
||||
}
|
||||
|
||||
static void init_pins(void) {
|
||||
unselect_rows();
|
||||
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
|
||||
setPinInputHigh(col_pins[x]);
|
||||
}
|
||||
unselect_rows();
|
||||
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
|
||||
setPinInputHigh(col_pins[x]);
|
||||
}
|
||||
}
|
||||
|
||||
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
|
||||
// Store last value of row prior to reading
|
||||
matrix_row_t last_row_value = current_matrix[current_row];
|
||||
// Store last value of row prior to reading
|
||||
matrix_row_t last_row_value = current_matrix[current_row];
|
||||
|
||||
// Clear data in matrix row
|
||||
current_matrix[current_row] = 0;
|
||||
// Clear data in matrix row
|
||||
current_matrix[current_row] = 0;
|
||||
|
||||
// Select row and wait for row selecton to stabilize
|
||||
select_row(current_row);
|
||||
wait_us(30);
|
||||
// Select row and wait for row selecton to stabilize
|
||||
select_row(current_row);
|
||||
wait_us(30);
|
||||
|
||||
// For each col...
|
||||
for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
|
||||
// Populate the matrix row with the state of the col pin
|
||||
current_matrix[current_row] |= readPin(col_pins[col_index]) ? 0 : (ROW_SHIFTER << col_index);
|
||||
}
|
||||
// For each col...
|
||||
for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
|
||||
// Populate the matrix row with the state of the col pin
|
||||
current_matrix[current_row] |= readPin(col_pins[col_index]) ? 0 : (ROW_SHIFTER << col_index);
|
||||
}
|
||||
|
||||
// Unselect row
|
||||
unselect_row(current_row);
|
||||
// Unselect row
|
||||
unselect_row(current_row);
|
||||
|
||||
return (last_row_value != current_matrix[current_row]);
|
||||
return (last_row_value != current_matrix[current_row]);
|
||||
}
|
||||
|
||||
#elif (DIODE_DIRECTION == ROW2COL)
|
||||
|
||||
static void select_col(uint8_t col) {
|
||||
setPinOutput(col_pins[col]);
|
||||
writePinLow(col_pins[col]);
|
||||
setPinOutput(col_pins[col]);
|
||||
writePinLow(col_pins[col]);
|
||||
}
|
||||
|
||||
static void unselect_col(uint8_t col) { setPinInputHigh(col_pins[col]); }
|
||||
|
||||
static void unselect_cols(void) {
|
||||
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
|
||||
setPinInputHigh(col_pins[x]);
|
||||
}
|
||||
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
|
||||
setPinInputHigh(col_pins[x]);
|
||||
}
|
||||
}
|
||||
|
||||
static void init_pins(void) {
|
||||
unselect_cols();
|
||||
for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
|
||||
setPinInputHigh(row_pins[x]);
|
||||
}
|
||||
unselect_cols();
|
||||
for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
|
||||
setPinInputHigh(row_pins[x]);
|
||||
}
|
||||
}
|
||||
|
||||
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
|
||||
bool matrix_changed = false;
|
||||
bool matrix_changed = false;
|
||||
|
||||
// Select col and wait for col selecton to stabilize
|
||||
select_col(current_col);
|
||||
wait_us(30);
|
||||
// Select col and wait for col selecton to stabilize
|
||||
select_col(current_col);
|
||||
wait_us(30);
|
||||
|
||||
// For each row...
|
||||
for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) {
|
||||
// Store last value of row prior to reading
|
||||
matrix_row_t last_row_value = current_matrix[row_index];
|
||||
// For each row...
|
||||
for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) {
|
||||
// Store last value of row prior to reading
|
||||
matrix_row_t last_row_value = current_matrix[row_index];
|
||||
|
||||
// Check row pin state
|
||||
if (readPin(row_pins[row_index])) {
|
||||
// Pin HI, clear col bit
|
||||
current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
|
||||
} else {
|
||||
// Pin LO, set col bit
|
||||
current_matrix[row_index] |= (ROW_SHIFTER << current_col);
|
||||
// Check row pin state
|
||||
if (readPin(row_pins[row_index])) {
|
||||
// Pin HI, clear col bit
|
||||
current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
|
||||
} else {
|
||||
// Pin LO, set col bit
|
||||
current_matrix[row_index] |= (ROW_SHIFTER << current_col);
|
||||
}
|
||||
|
||||
// Determine if the matrix changed state
|
||||
if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
|
||||
matrix_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if the matrix changed state
|
||||
if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
|
||||
matrix_changed = true;
|
||||
}
|
||||
}
|
||||
// Unselect col
|
||||
unselect_col(current_col);
|
||||
|
||||
// Unselect col
|
||||
unselect_col(current_col);
|
||||
|
||||
return matrix_changed;
|
||||
return matrix_changed;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void matrix_init(void) {
|
||||
debug_enable = true;
|
||||
debug_matrix = true;
|
||||
debug_mouse = true;
|
||||
debug_enable = true;
|
||||
debug_matrix = true;
|
||||
debug_mouse = true;
|
||||
|
||||
// Set pinout for right half if pinout for that half is defined
|
||||
if (!isLeftHand) {
|
||||
// Set pinout for right half if pinout for that half is defined
|
||||
if (!isLeftHand) {
|
||||
#ifdef DIRECT_PINS_RIGHT
|
||||
const pin_t direct_pins_right[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS_RIGHT;
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
for (uint8_t j = 0; j < MATRIX_COLS; j++) {
|
||||
direct_pins[i][j] = direct_pins_right[i][j];
|
||||
}
|
||||
}
|
||||
const pin_t direct_pins_right[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS_RIGHT;
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
for (uint8_t j = 0; j < MATRIX_COLS; j++) {
|
||||
direct_pins[i][j] = direct_pins_right[i][j];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef MATRIX_ROW_PINS_RIGHT
|
||||
const pin_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT;
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
row_pins[i] = row_pins_right[i];
|
||||
}
|
||||
const pin_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT;
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
row_pins[i] = row_pins_right[i];
|
||||
}
|
||||
#endif
|
||||
#ifdef MATRIX_COL_PINS_RIGHT
|
||||
const pin_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT;
|
||||
for (uint8_t i = 0; i < MATRIX_COLS; i++) {
|
||||
col_pins[i] = col_pins_right[i];
|
||||
}
|
||||
const pin_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT;
|
||||
for (uint8_t i = 0; i < MATRIX_COLS; i++) {
|
||||
col_pins[i] = col_pins_right[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
thisHand = isLeftHand ? 0 : (ROWS_PER_HAND);
|
||||
thatHand = ROWS_PER_HAND - thisHand;
|
||||
thisHand = isLeftHand ? 0 : (ROWS_PER_HAND);
|
||||
thatHand = ROWS_PER_HAND - thisHand;
|
||||
|
||||
// initialize key pins
|
||||
init_pins();
|
||||
// initialize key pins
|
||||
init_pins();
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = 0;
|
||||
}
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = 0;
|
||||
}
|
||||
|
||||
debounce_init(ROWS_PER_HAND);
|
||||
debounce_init(ROWS_PER_HAND);
|
||||
|
||||
matrix_init_quantum();
|
||||
matrix_init_quantum();
|
||||
}
|
||||
|
||||
uint8_t _matrix_scan(void) {
|
||||
bool changed = false;
|
||||
bool changed = false;
|
||||
|
||||
#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
|
||||
// Set row, read cols
|
||||
for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) {
|
||||
changed |= read_cols_on_row(raw_matrix, current_row);
|
||||
}
|
||||
// Set row, read cols
|
||||
for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) {
|
||||
changed |= read_cols_on_row(raw_matrix, current_row);
|
||||
}
|
||||
#elif (DIODE_DIRECTION == ROW2COL)
|
||||
// Set col, read rows
|
||||
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
|
||||
changed |= read_rows_on_col(raw_matrix, current_col);
|
||||
}
|
||||
// Set col, read rows
|
||||
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
|
||||
changed |= read_rows_on_col(raw_matrix, current_col);
|
||||
}
|
||||
#endif
|
||||
|
||||
debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed);
|
||||
debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed);
|
||||
|
||||
return (uint8_t)changed;
|
||||
return (uint8_t)changed;
|
||||
}
|
||||
|
||||
uint8_t matrix_scan(void) {
|
||||
uint8_t ret = _matrix_scan();
|
||||
uint8_t ret = _matrix_scan();
|
||||
|
||||
if (is_keyboard_master()) {
|
||||
static uint8_t error_count;
|
||||
if (is_keyboard_master()) {
|
||||
static uint8_t error_count;
|
||||
|
||||
if (!transport_master(matrix + thatHand)) {
|
||||
error_count++;
|
||||
if (!transport_master(matrix + thatHand)) {
|
||||
error_count++;
|
||||
|
||||
if (error_count > ERROR_DISCONNECT_COUNT) {
|
||||
// reset other half if disconnected
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
matrix[thatHand + i] = 0;
|
||||
if (error_count > ERROR_DISCONNECT_COUNT) {
|
||||
// reset other half if disconnected
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
matrix[thatHand + i] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
matrix_scan_quantum();
|
||||
} else {
|
||||
error_count = 0;
|
||||
transport_slave(matrix + thisHand);
|
||||
#ifdef ENCODER_ENABLE
|
||||
encoder_read();
|
||||
#endif
|
||||
matrix_slave_scan_user();
|
||||
}
|
||||
|
||||
matrix_scan_quantum();
|
||||
} else {
|
||||
transport_slave(matrix + thisHand);
|
||||
#ifdef ENCODER_ENABLE
|
||||
encoder_read();
|
||||
#endif
|
||||
matrix_slave_scan_user();
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
#if defined(USE_I2C) || defined(EH)
|
||||
// When using I2C, using rgblight implicitly involves split support.
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_SPLIT)
|
||||
#define RGBLIGHT_SPLIT
|
||||
#endif
|
||||
// When using I2C, using rgblight implicitly involves split support.
|
||||
# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_SPLIT)
|
||||
# define RGBLIGHT_SPLIT
|
||||
# endif
|
||||
|
||||
#ifndef F_SCL
|
||||
#define F_SCL 100000UL // SCL frequency
|
||||
#endif
|
||||
# ifndef F_SCL
|
||||
# define F_SCL 100000UL // SCL frequency
|
||||
# endif
|
||||
|
||||
#else // use serial
|
||||
// When using serial, the user must define RGBLIGHT_SPLIT explicitly
|
||||
// in config.h as needed.
|
||||
// see quantum/rgblight_post_config.h
|
||||
#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
// When using serial and RGBLIGHT_SPLIT need separate transaction
|
||||
#define SERIAL_USE_MULTI_TRANSACTION
|
||||
#endif
|
||||
// When using serial, the user must define RGBLIGHT_SPLIT explicitly
|
||||
// in config.h as needed.
|
||||
// see quantum/rgblight_post_config.h
|
||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
// When using serial and RGBLIGHT_SPLIT need separate transaction
|
||||
# define SERIAL_USE_MULTI_TRANSACTION
|
||||
# endif
|
||||
#endif
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
#ifndef F_CPU
|
||||
#define F_CPU 16000000
|
||||
# define F_CPU 16000000
|
||||
#endif
|
||||
|
||||
#include <avr/io.h>
|
||||
|
@ -21,252 +21,224 @@
|
|||
|
||||
#ifdef SOFT_SERIAL_PIN
|
||||
|
||||
#ifdef __AVR_ATmega32U4__
|
||||
// if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial.
|
||||
#ifdef USE_AVR_I2C
|
||||
#if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1
|
||||
#error Using ATmega32U4 I2C, so can not use PD0, PD1
|
||||
#endif
|
||||
#endif
|
||||
# ifdef __AVR_ATmega32U4__
|
||||
// if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial.
|
||||
# ifdef USE_AVR_I2C
|
||||
# if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1
|
||||
# error Using ATmega32U4 I2C, so can not use PD0, PD1
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin) & 0xF), \
|
||||
PORTx_ADDRESS(pin) |= _BV((pin) & 0xF))
|
||||
#define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin) & 0xF))
|
||||
#define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin) & 0xF))
|
||||
#define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin) & 0xF))
|
||||
#define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin) & 0xF)))
|
||||
# define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
|
||||
# define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF))
|
||||
# define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
|
||||
# define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
|
||||
# define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF)))
|
||||
|
||||
#if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3
|
||||
#if SOFT_SERIAL_PIN == D0
|
||||
#define EIMSK_BIT _BV(INT0)
|
||||
#define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01)))
|
||||
#define SERIAL_PIN_INTERRUPT INT0_vect
|
||||
#elif SOFT_SERIAL_PIN == D1
|
||||
#define EIMSK_BIT _BV(INT1)
|
||||
#define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11)))
|
||||
#define SERIAL_PIN_INTERRUPT INT1_vect
|
||||
#elif SOFT_SERIAL_PIN == D2
|
||||
#define EIMSK_BIT _BV(INT2)
|
||||
#define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21)))
|
||||
#define SERIAL_PIN_INTERRUPT INT2_vect
|
||||
#elif SOFT_SERIAL_PIN == D3
|
||||
#define EIMSK_BIT _BV(INT3)
|
||||
#define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31)))
|
||||
#define SERIAL_PIN_INTERRUPT INT3_vect
|
||||
#endif
|
||||
#elif SOFT_SERIAL_PIN == E6
|
||||
#define EIMSK_BIT _BV(INT6)
|
||||
#define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61)))
|
||||
#define SERIAL_PIN_INTERRUPT INT6_vect
|
||||
#else
|
||||
#error invalid SOFT_SERIAL_PIN value
|
||||
#endif
|
||||
# if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3
|
||||
# if SOFT_SERIAL_PIN == D0
|
||||
# define EIMSK_BIT _BV(INT0)
|
||||
# define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01)))
|
||||
# define SERIAL_PIN_INTERRUPT INT0_vect
|
||||
# elif SOFT_SERIAL_PIN == D1
|
||||
# define EIMSK_BIT _BV(INT1)
|
||||
# define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11)))
|
||||
# define SERIAL_PIN_INTERRUPT INT1_vect
|
||||
# elif SOFT_SERIAL_PIN == D2
|
||||
# define EIMSK_BIT _BV(INT2)
|
||||
# define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21)))
|
||||
# define SERIAL_PIN_INTERRUPT INT2_vect
|
||||
# elif SOFT_SERIAL_PIN == D3
|
||||
# define EIMSK_BIT _BV(INT3)
|
||||
# define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31)))
|
||||
# define SERIAL_PIN_INTERRUPT INT3_vect
|
||||
# endif
|
||||
# elif SOFT_SERIAL_PIN == E6
|
||||
# define EIMSK_BIT _BV(INT6)
|
||||
# define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61)))
|
||||
# define SERIAL_PIN_INTERRUPT INT6_vect
|
||||
# else
|
||||
# error invalid SOFT_SERIAL_PIN value
|
||||
# endif
|
||||
|
||||
#else
|
||||
#error serial.c now support ATmega32U4 only
|
||||
#endif
|
||||
# else
|
||||
# error serial.c now support ATmega32U4 only
|
||||
# endif
|
||||
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
#define NO_INLINE __attribute__((noinline))
|
||||
#define _delay_sub_us(x) __builtin_avr_delay_cycles(x)
|
||||
# define ALWAYS_INLINE __attribute__((always_inline))
|
||||
# define NO_INLINE __attribute__((noinline))
|
||||
# define _delay_sub_us(x) __builtin_avr_delay_cycles(x)
|
||||
|
||||
// parity check
|
||||
#define ODD_PARITY 1
|
||||
#define EVEN_PARITY 0
|
||||
#define PARITY EVEN_PARITY
|
||||
# define ODD_PARITY 1
|
||||
# define EVEN_PARITY 0
|
||||
# define PARITY EVEN_PARITY
|
||||
|
||||
#ifdef SERIAL_DELAY
|
||||
// custom setup in config.h
|
||||
// #define TID_SEND_ADJUST 2
|
||||
// #define SERIAL_DELAY 6 // micro sec
|
||||
// #define READ_WRITE_START_ADJUST 30 // cycles
|
||||
// #define READ_WRITE_WIDTH_ADJUST 8 // cycles
|
||||
#else
|
||||
# ifdef SERIAL_DELAY
|
||||
// custom setup in config.h
|
||||
// #define TID_SEND_ADJUST 2
|
||||
// #define SERIAL_DELAY 6 // micro sec
|
||||
// #define READ_WRITE_START_ADJUST 30 // cycles
|
||||
// #define READ_WRITE_WIDTH_ADJUST 8 // cycles
|
||||
# else
|
||||
// ============ Standard setups ============
|
||||
|
||||
#ifndef SELECT_SOFT_SERIAL_SPEED
|
||||
#define SELECT_SOFT_SERIAL_SPEED 1
|
||||
# ifndef SELECT_SOFT_SERIAL_SPEED
|
||||
# define SELECT_SOFT_SERIAL_SPEED 1
|
||||
// 0: about 189kbps (Experimental only)
|
||||
// 1: about 137kbps (default)
|
||||
// 2: about 75kbps
|
||||
// 3: about 39kbps
|
||||
// 4: about 26kbps
|
||||
// 5: about 20kbps
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#if __GNUC__ < 6
|
||||
#define TID_SEND_ADJUST 14
|
||||
#else
|
||||
#define TID_SEND_ADJUST 2
|
||||
#endif
|
||||
# if __GNUC__ < 6
|
||||
# define TID_SEND_ADJUST 14
|
||||
# else
|
||||
# define TID_SEND_ADJUST 2
|
||||
# endif
|
||||
|
||||
#if SELECT_SOFT_SERIAL_SPEED == 0
|
||||
// Very High speed
|
||||
#define SERIAL_DELAY 4 // micro sec
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_START_ADJUST 33 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_START_ADJUST 34 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 1
|
||||
// High speed
|
||||
#define SERIAL_DELAY 6 // micro sec
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_START_ADJUST 33 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 2
|
||||
// Middle speed
|
||||
#define SERIAL_DELAY 12 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 3
|
||||
// Low speed
|
||||
#define SERIAL_DELAY 24 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 4
|
||||
// Very Low speed
|
||||
#define SERIAL_DELAY 36 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 5
|
||||
// Ultra Low speed
|
||||
#define SERIAL_DELAY 48 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#else
|
||||
#error invalid SELECT_SOFT_SERIAL_SPEED value
|
||||
#endif /* SELECT_SOFT_SERIAL_SPEED */
|
||||
#endif /* SERIAL_DELAY */
|
||||
# if SELECT_SOFT_SERIAL_SPEED == 0
|
||||
// Very High speed
|
||||
# define SERIAL_DELAY 4 // micro sec
|
||||
# if __GNUC__ < 6
|
||||
# define READ_WRITE_START_ADJUST 33 // cycles
|
||||
# define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
# else
|
||||
# define READ_WRITE_START_ADJUST 34 // cycles
|
||||
# define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
# endif
|
||||
# elif SELECT_SOFT_SERIAL_SPEED == 1
|
||||
// High speed
|
||||
# define SERIAL_DELAY 6 // micro sec
|
||||
# if __GNUC__ < 6
|
||||
# define READ_WRITE_START_ADJUST 30 // cycles
|
||||
# define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
# else
|
||||
# define READ_WRITE_START_ADJUST 33 // cycles
|
||||
# define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
# endif
|
||||
# elif SELECT_SOFT_SERIAL_SPEED == 2
|
||||
// Middle speed
|
||||
# define SERIAL_DELAY 12 // micro sec
|
||||
# define READ_WRITE_START_ADJUST 30 // cycles
|
||||
# if __GNUC__ < 6
|
||||
# define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
# else
|
||||
# define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
# endif
|
||||
# elif SELECT_SOFT_SERIAL_SPEED == 3
|
||||
// Low speed
|
||||
# define SERIAL_DELAY 24 // micro sec
|
||||
# define READ_WRITE_START_ADJUST 30 // cycles
|
||||
# if __GNUC__ < 6
|
||||
# define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
# else
|
||||
# define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
# endif
|
||||
# elif SELECT_SOFT_SERIAL_SPEED == 4
|
||||
// Very Low speed
|
||||
# define SERIAL_DELAY 36 // micro sec
|
||||
# define READ_WRITE_START_ADJUST 30 // cycles
|
||||
# if __GNUC__ < 6
|
||||
# define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
# else
|
||||
# define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
# endif
|
||||
# elif SELECT_SOFT_SERIAL_SPEED == 5
|
||||
// Ultra Low speed
|
||||
# define SERIAL_DELAY 48 // micro sec
|
||||
# define READ_WRITE_START_ADJUST 30 // cycles
|
||||
# if __GNUC__ < 6
|
||||
# define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
# else
|
||||
# define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
# endif
|
||||
# else
|
||||
# error invalid SELECT_SOFT_SERIAL_SPEED value
|
||||
# endif /* SELECT_SOFT_SERIAL_SPEED */
|
||||
# endif /* SERIAL_DELAY */
|
||||
|
||||
#define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2)
|
||||
#define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2)
|
||||
# define SERIAL_DELAY_HALF1 (SERIAL_DELAY / 2)
|
||||
# define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY / 2)
|
||||
|
||||
#define SLAVE_INT_WIDTH_US 1
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
#define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY
|
||||
#else
|
||||
#define SLAVE_INT_ACK_WIDTH_UNIT 2
|
||||
#define SLAVE_INT_ACK_WIDTH 4
|
||||
#endif
|
||||
# define SLAVE_INT_WIDTH_US 1
|
||||
# ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
# define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY
|
||||
# else
|
||||
# define SLAVE_INT_ACK_WIDTH_UNIT 2
|
||||
# define SLAVE_INT_ACK_WIDTH 4
|
||||
# endif
|
||||
|
||||
static SSTD_t *Transaction_table = NULL;
|
||||
static SSTD_t *Transaction_table = NULL;
|
||||
static uint8_t Transaction_table_size = 0;
|
||||
|
||||
inline static void serial_delay(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_delay(void) {
|
||||
_delay_us(SERIAL_DELAY);
|
||||
}
|
||||
inline static void serial_delay(void) { _delay_us(SERIAL_DELAY); }
|
||||
|
||||
inline static void serial_delay_half1(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_delay_half1(void) {
|
||||
_delay_us(SERIAL_DELAY_HALF1);
|
||||
}
|
||||
inline static void serial_delay_half1(void) { _delay_us(SERIAL_DELAY_HALF1); }
|
||||
|
||||
inline static void serial_delay_half2(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_delay_half2(void) {
|
||||
_delay_us(SERIAL_DELAY_HALF2);
|
||||
}
|
||||
inline static void serial_delay_half2(void) { _delay_us(SERIAL_DELAY_HALF2); }
|
||||
|
||||
inline static void serial_output(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_output(void) {
|
||||
setPinOutput(SOFT_SERIAL_PIN);
|
||||
}
|
||||
inline static void serial_output(void) { setPinOutput(SOFT_SERIAL_PIN); }
|
||||
|
||||
// make the serial pin an input with pull-up resistor
|
||||
inline static void serial_input_with_pullup(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_input_with_pullup(void) {
|
||||
setPinInputHigh(SOFT_SERIAL_PIN);
|
||||
}
|
||||
inline static void serial_input_with_pullup(void) { setPinInputHigh(SOFT_SERIAL_PIN); }
|
||||
|
||||
inline static uint8_t serial_read_pin(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
uint8_t serial_read_pin(void) {
|
||||
return !! readPin(SOFT_SERIAL_PIN);
|
||||
}
|
||||
inline static uint8_t serial_read_pin(void) { return !!readPin(SOFT_SERIAL_PIN); }
|
||||
|
||||
inline static void serial_low(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_low(void) {
|
||||
writePinLow(SOFT_SERIAL_PIN);
|
||||
}
|
||||
inline static void serial_low(void) { writePinLow(SOFT_SERIAL_PIN); }
|
||||
|
||||
inline static void serial_high(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_high(void) {
|
||||
writePinHigh(SOFT_SERIAL_PIN);
|
||||
}
|
||||
inline static void serial_high(void) { writePinHigh(SOFT_SERIAL_PIN); }
|
||||
|
||||
void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size)
|
||||
{
|
||||
Transaction_table = sstd_table;
|
||||
void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size) {
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
serial_output();
|
||||
serial_high();
|
||||
}
|
||||
|
||||
void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size)
|
||||
{
|
||||
Transaction_table = sstd_table;
|
||||
void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size) {
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
serial_input_with_pullup();
|
||||
|
||||
// Enable INT0-INT3,INT6
|
||||
EIMSK |= EIMSK_BIT;
|
||||
#if SOFT_SERIAL_PIN == E6
|
||||
# if SOFT_SERIAL_PIN == E6
|
||||
// Trigger on falling edge of INT6
|
||||
EICRB &= EICRx_BIT;
|
||||
#else
|
||||
# else
|
||||
// Trigger on falling edge of INT0-INT3
|
||||
EICRA &= EICRx_BIT;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
// Used by the sender to synchronize timing with the reciver.
|
||||
static void sync_recv(void) NO_INLINE;
|
||||
static
|
||||
void sync_recv(void) {
|
||||
for (uint8_t i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) {
|
||||
}
|
||||
// This shouldn't hang if the target disconnects because the
|
||||
// serial line will float to high if the target does disconnect.
|
||||
while (!serial_read_pin());
|
||||
static void sync_recv(void) {
|
||||
for (uint8_t i = 0; i < SERIAL_DELAY * 5 && serial_read_pin(); i++) {
|
||||
}
|
||||
// This shouldn't hang if the target disconnects because the
|
||||
// serial line will float to high if the target does disconnect.
|
||||
while (!serial_read_pin())
|
||||
;
|
||||
}
|
||||
|
||||
// Used by the reciver to send a synchronization signal to the sender.
|
||||
static void sync_send(void) NO_INLINE;
|
||||
static
|
||||
void sync_send(void) {
|
||||
serial_low();
|
||||
serial_delay();
|
||||
serial_high();
|
||||
static void sync_send(void) {
|
||||
serial_low();
|
||||
serial_delay();
|
||||
serial_high();
|
||||
}
|
||||
|
||||
// Reads a byte from the serial line
|
||||
|
@ -274,92 +246,94 @@ static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) NO_INLINE;
|
|||
static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) {
|
||||
uint8_t byte, i, p, pb;
|
||||
|
||||
_delay_sub_us(READ_WRITE_START_ADJUST);
|
||||
for( i = 0, byte = 0, p = PARITY; i < bit; i++ ) {
|
||||
serial_delay_half1(); // read the middle of pulses
|
||||
if( serial_read_pin() ) {
|
||||
byte = (byte << 1) | 1; p ^= 1;
|
||||
} else {
|
||||
byte = (byte << 1) | 0; p ^= 0;
|
||||
}
|
||||
_delay_sub_us(READ_WRITE_WIDTH_ADJUST);
|
||||
serial_delay_half2();
|
||||
}
|
||||
/* recive parity bit */
|
||||
serial_delay_half1(); // read the middle of pulses
|
||||
pb = serial_read_pin();
|
||||
_delay_sub_us(READ_WRITE_WIDTH_ADJUST);
|
||||
serial_delay_half2();
|
||||
_delay_sub_us(READ_WRITE_START_ADJUST);
|
||||
for (i = 0, byte = 0, p = PARITY; i < bit; i++) {
|
||||
serial_delay_half1(); // read the middle of pulses
|
||||
if (serial_read_pin()) {
|
||||
byte = (byte << 1) | 1;
|
||||
p ^= 1;
|
||||
} else {
|
||||
byte = (byte << 1) | 0;
|
||||
p ^= 0;
|
||||
}
|
||||
_delay_sub_us(READ_WRITE_WIDTH_ADJUST);
|
||||
serial_delay_half2();
|
||||
}
|
||||
/* recive parity bit */
|
||||
serial_delay_half1(); // read the middle of pulses
|
||||
pb = serial_read_pin();
|
||||
_delay_sub_us(READ_WRITE_WIDTH_ADJUST);
|
||||
serial_delay_half2();
|
||||
|
||||
*pterrcount += (p != pb)? 1 : 0;
|
||||
*pterrcount += (p != pb) ? 1 : 0;
|
||||
|
||||
return byte;
|
||||
return byte;
|
||||
}
|
||||
|
||||
// Sends a byte with MSB ordering
|
||||
void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE;
|
||||
void serial_write_chunk(uint8_t data, uint8_t bit) {
|
||||
uint8_t b, p;
|
||||
for( p = PARITY, b = 1<<(bit-1); b ; b >>= 1) {
|
||||
if(data & b) {
|
||||
serial_high(); p ^= 1;
|
||||
for (p = PARITY, b = 1 << (bit - 1); b; b >>= 1) {
|
||||
if (data & b) {
|
||||
serial_high();
|
||||
p ^= 1;
|
||||
} else {
|
||||
serial_low(); p ^= 0;
|
||||
serial_low();
|
||||
p ^= 0;
|
||||
}
|
||||
serial_delay();
|
||||
}
|
||||
/* send parity bit */
|
||||
if(p & 1) { serial_high(); }
|
||||
else { serial_low(); }
|
||||
if (p & 1) {
|
||||
serial_high();
|
||||
} else {
|
||||
serial_low();
|
||||
}
|
||||
serial_delay();
|
||||
|
||||
serial_low(); // sync_send() / senc_recv() need raise edge
|
||||
serial_low(); // sync_send() / senc_recv() need raise edge
|
||||
}
|
||||
|
||||
static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
|
||||
static
|
||||
void serial_send_packet(uint8_t *buffer, uint8_t size) {
|
||||
for (uint8_t i = 0; i < size; ++i) {
|
||||
uint8_t data;
|
||||
data = buffer[i];
|
||||
sync_send();
|
||||
serial_write_chunk(data,8);
|
||||
}
|
||||
static void serial_send_packet(uint8_t *buffer, uint8_t size) {
|
||||
for (uint8_t i = 0; i < size; ++i) {
|
||||
uint8_t data;
|
||||
data = buffer[i];
|
||||
sync_send();
|
||||
serial_write_chunk(data, 8);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
|
||||
static
|
||||
uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) {
|
||||
uint8_t pecount = 0;
|
||||
for (uint8_t i = 0; i < size; ++i) {
|
||||
uint8_t data;
|
||||
sync_recv();
|
||||
data = serial_read_chunk(&pecount, 8);
|
||||
buffer[i] = data;
|
||||
}
|
||||
return pecount == 0;
|
||||
static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) {
|
||||
uint8_t pecount = 0;
|
||||
for (uint8_t i = 0; i < size; ++i) {
|
||||
uint8_t data;
|
||||
sync_recv();
|
||||
data = serial_read_chunk(&pecount, 8);
|
||||
buffer[i] = data;
|
||||
}
|
||||
return pecount == 0;
|
||||
}
|
||||
|
||||
inline static
|
||||
void change_sender2reciver(void) {
|
||||
sync_send(); //0
|
||||
serial_delay_half1(); //1
|
||||
serial_low(); //2
|
||||
serial_input_with_pullup(); //2
|
||||
serial_delay_half1(); //3
|
||||
inline static void change_sender2reciver(void) {
|
||||
sync_send(); // 0
|
||||
serial_delay_half1(); // 1
|
||||
serial_low(); // 2
|
||||
serial_input_with_pullup(); // 2
|
||||
serial_delay_half1(); // 3
|
||||
}
|
||||
|
||||
inline static
|
||||
void change_reciver2sender(void) {
|
||||
sync_recv(); //0
|
||||
serial_delay(); //1
|
||||
serial_low(); //3
|
||||
serial_output(); //3
|
||||
serial_delay_half1(); //4
|
||||
inline static void change_reciver2sender(void) {
|
||||
sync_recv(); // 0
|
||||
serial_delay(); // 1
|
||||
serial_low(); // 3
|
||||
serial_output(); // 3
|
||||
serial_delay_half1(); // 4
|
||||
}
|
||||
|
||||
static inline uint8_t nibble_bits_count(uint8_t bits)
|
||||
{
|
||||
static inline uint8_t nibble_bits_count(uint8_t bits) {
|
||||
bits = (bits & 0x5) + (bits >> 1 & 0x5);
|
||||
bits = (bits & 0x3) + (bits >> 2 & 0x3);
|
||||
return bits;
|
||||
|
@ -367,51 +341,47 @@ static inline uint8_t nibble_bits_count(uint8_t bits)
|
|||
|
||||
// interrupt handle to be used by the target device
|
||||
ISR(SERIAL_PIN_INTERRUPT) {
|
||||
# ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
serial_low();
|
||||
serial_output();
|
||||
SSTD_t *trans = Transaction_table;
|
||||
# else
|
||||
// recive transaction table index
|
||||
uint8_t tid, bits;
|
||||
uint8_t pecount = 0;
|
||||
sync_recv();
|
||||
bits = serial_read_chunk(&pecount, 7);
|
||||
tid = bits >> 3;
|
||||
bits = (bits & 7) != nibble_bits_count(tid);
|
||||
if (bits || pecount > 0 || tid > Transaction_table_size) {
|
||||
return;
|
||||
}
|
||||
serial_delay_half1();
|
||||
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
serial_low();
|
||||
serial_output();
|
||||
SSTD_t *trans = Transaction_table;
|
||||
#else
|
||||
// recive transaction table index
|
||||
uint8_t tid, bits;
|
||||
uint8_t pecount = 0;
|
||||
sync_recv();
|
||||
bits = serial_read_chunk(&pecount,7);
|
||||
tid = bits>>3;
|
||||
bits = (bits&7) != nibble_bits_count(tid);
|
||||
if( bits || pecount> 0 || tid > Transaction_table_size ) {
|
||||
return;
|
||||
}
|
||||
serial_delay_half1();
|
||||
serial_high(); // response step1 low->high
|
||||
serial_output();
|
||||
_delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT * SLAVE_INT_ACK_WIDTH);
|
||||
SSTD_t *trans = &Transaction_table[tid];
|
||||
serial_low(); // response step2 ack high->low
|
||||
# endif
|
||||
|
||||
serial_high(); // response step1 low->high
|
||||
serial_output();
|
||||
_delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT*SLAVE_INT_ACK_WIDTH);
|
||||
SSTD_t *trans = &Transaction_table[tid];
|
||||
serial_low(); // response step2 ack high->low
|
||||
#endif
|
||||
// target send phase
|
||||
if (trans->target2initiator_buffer_size > 0) serial_send_packet((uint8_t *)trans->target2initiator_buffer, trans->target2initiator_buffer_size);
|
||||
// target switch to input
|
||||
change_sender2reciver();
|
||||
|
||||
// target send phase
|
||||
if( trans->target2initiator_buffer_size > 0 )
|
||||
serial_send_packet((uint8_t *)trans->target2initiator_buffer,
|
||||
trans->target2initiator_buffer_size);
|
||||
// target switch to input
|
||||
change_sender2reciver();
|
||||
// target recive phase
|
||||
if (trans->initiator2target_buffer_size > 0) {
|
||||
if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer, trans->initiator2target_buffer_size)) {
|
||||
*trans->status = TRANSACTION_ACCEPTED;
|
||||
} else {
|
||||
*trans->status = TRANSACTION_DATA_ERROR;
|
||||
}
|
||||
} else {
|
||||
*trans->status = TRANSACTION_ACCEPTED;
|
||||
}
|
||||
|
||||
// target recive phase
|
||||
if( trans->initiator2target_buffer_size > 0 ) {
|
||||
if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer,
|
||||
trans->initiator2target_buffer_size) ) {
|
||||
*trans->status = TRANSACTION_ACCEPTED;
|
||||
} else {
|
||||
*trans->status = TRANSACTION_DATA_ERROR;
|
||||
}
|
||||
} else {
|
||||
*trans->status = TRANSACTION_ACCEPTED;
|
||||
}
|
||||
|
||||
sync_recv(); //weit initiator output to high
|
||||
sync_recv(); // weit initiator output to high
|
||||
}
|
||||
|
||||
/////////
|
||||
|
@ -424,105 +394,103 @@ ISR(SERIAL_PIN_INTERRUPT) {
|
|||
// TRANSACTION_NO_RESPONSE
|
||||
// TRANSACTION_DATA_ERROR
|
||||
// this code is very time dependent, so we need to disable interrupts
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void) {
|
||||
SSTD_t *trans = Transaction_table;
|
||||
#else
|
||||
int soft_serial_transaction(int sstd_index) {
|
||||
if( sstd_index > Transaction_table_size )
|
||||
return TRANSACTION_TYPE_ERROR;
|
||||
SSTD_t *trans = &Transaction_table[sstd_index];
|
||||
#endif
|
||||
cli();
|
||||
# ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void) {
|
||||
SSTD_t *trans = Transaction_table;
|
||||
# else
|
||||
int soft_serial_transaction(int sstd_index) {
|
||||
if (sstd_index > Transaction_table_size) return TRANSACTION_TYPE_ERROR;
|
||||
SSTD_t *trans = &Transaction_table[sstd_index];
|
||||
# endif
|
||||
cli();
|
||||
|
||||
// signal to the target that we want to start a transaction
|
||||
serial_output();
|
||||
serial_low();
|
||||
_delay_us(SLAVE_INT_WIDTH_US);
|
||||
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
// wait for the target response
|
||||
serial_input_with_pullup();
|
||||
_delay_us(SLAVE_INT_RESPONSE_TIME);
|
||||
|
||||
// check if the target is present
|
||||
if (serial_read_pin()) {
|
||||
// target failed to pull the line low, assume not present
|
||||
// signal to the target that we want to start a transaction
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_NO_RESPONSE;
|
||||
serial_low();
|
||||
_delay_us(SLAVE_INT_WIDTH_US);
|
||||
|
||||
# ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
// wait for the target response
|
||||
serial_input_with_pullup();
|
||||
_delay_us(SLAVE_INT_RESPONSE_TIME);
|
||||
|
||||
// check if the target is present
|
||||
if (serial_read_pin()) {
|
||||
// target failed to pull the line low, assume not present
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_NO_RESPONSE;
|
||||
sei();
|
||||
return TRANSACTION_NO_RESPONSE;
|
||||
}
|
||||
|
||||
# else
|
||||
// send transaction table index
|
||||
int tid = (sstd_index << 3) | (7 & nibble_bits_count(sstd_index));
|
||||
sync_send();
|
||||
_delay_sub_us(TID_SEND_ADJUST);
|
||||
serial_write_chunk(tid, 7);
|
||||
serial_delay_half1();
|
||||
|
||||
// wait for the target response (step1 low->high)
|
||||
serial_input_with_pullup();
|
||||
while (!serial_read_pin()) {
|
||||
_delay_sub_us(2);
|
||||
}
|
||||
|
||||
// check if the target is present (step2 high->low)
|
||||
for (int i = 0; serial_read_pin(); i++) {
|
||||
if (i > SLAVE_INT_ACK_WIDTH + 1) {
|
||||
// slave failed to pull the line low, assume not present
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_NO_RESPONSE;
|
||||
sei();
|
||||
return TRANSACTION_NO_RESPONSE;
|
||||
}
|
||||
_delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT);
|
||||
}
|
||||
# endif
|
||||
|
||||
// initiator recive phase
|
||||
// if the target is present syncronize with it
|
||||
if (trans->target2initiator_buffer_size > 0) {
|
||||
if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer, trans->target2initiator_buffer_size)) {
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_DATA_ERROR;
|
||||
sei();
|
||||
return TRANSACTION_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// initiator switch to output
|
||||
change_reciver2sender();
|
||||
|
||||
// initiator send phase
|
||||
if (trans->initiator2target_buffer_size > 0) {
|
||||
serial_send_packet((uint8_t *)trans->initiator2target_buffer, trans->initiator2target_buffer_size);
|
||||
}
|
||||
|
||||
// always, release the line when not in use
|
||||
sync_send();
|
||||
|
||||
*trans->status = TRANSACTION_END;
|
||||
sei();
|
||||
return TRANSACTION_NO_RESPONSE;
|
||||
}
|
||||
|
||||
#else
|
||||
// send transaction table index
|
||||
int tid = (sstd_index<<3) | (7 & nibble_bits_count(sstd_index));
|
||||
sync_send();
|
||||
_delay_sub_us(TID_SEND_ADJUST);
|
||||
serial_write_chunk(tid, 7);
|
||||
serial_delay_half1();
|
||||
|
||||
// wait for the target response (step1 low->high)
|
||||
serial_input_with_pullup();
|
||||
while( !serial_read_pin() ) {
|
||||
_delay_sub_us(2);
|
||||
}
|
||||
|
||||
// check if the target is present (step2 high->low)
|
||||
for( int i = 0; serial_read_pin(); i++ ) {
|
||||
if (i > SLAVE_INT_ACK_WIDTH + 1) {
|
||||
// slave failed to pull the line low, assume not present
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_NO_RESPONSE;
|
||||
sei();
|
||||
return TRANSACTION_NO_RESPONSE;
|
||||
}
|
||||
_delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
// initiator recive phase
|
||||
// if the target is present syncronize with it
|
||||
if( trans->target2initiator_buffer_size > 0 ) {
|
||||
if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer,
|
||||
trans->target2initiator_buffer_size) ) {
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_DATA_ERROR;
|
||||
sei();
|
||||
return TRANSACTION_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// initiator switch to output
|
||||
change_reciver2sender();
|
||||
|
||||
// initiator send phase
|
||||
if( trans->initiator2target_buffer_size > 0 ) {
|
||||
serial_send_packet((uint8_t *)trans->initiator2target_buffer,
|
||||
trans->initiator2target_buffer_size);
|
||||
}
|
||||
|
||||
// always, release the line when not in use
|
||||
sync_send();
|
||||
|
||||
*trans->status = TRANSACTION_END;
|
||||
sei();
|
||||
return TRANSACTION_END;
|
||||
return TRANSACTION_END;
|
||||
}
|
||||
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
# ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_get_and_clean_status(int sstd_index) {
|
||||
SSTD_t *trans = &Transaction_table[sstd_index];
|
||||
cli();
|
||||
int retval = *trans->status;
|
||||
*trans->status = 0;;
|
||||
int retval = *trans->status;
|
||||
*trans->status = 0;
|
||||
;
|
||||
sei();
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -22,14 +22,14 @@
|
|||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
// Soft Serial Transaction Descriptor
|
||||
typedef struct _SSTD_t {
|
||||
typedef struct _SSTD_t {
|
||||
uint8_t *status;
|
||||
uint8_t initiator2target_buffer_size;
|
||||
uint8_t initiator2target_buffer_size;
|
||||
uint8_t *initiator2target_buffer;
|
||||
uint8_t target2initiator_buffer_size;
|
||||
uint8_t target2initiator_buffer_size;
|
||||
uint8_t *target2initiator_buffer;
|
||||
} SSTD_t;
|
||||
#define TID_LIMIT( table ) (sizeof(table) / sizeof(SSTD_t))
|
||||
#define TID_LIMIT(table) (sizeof(table) / sizeof(SSTD_t))
|
||||
|
||||
// initiator is transaction start side
|
||||
void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size);
|
||||
|
@ -39,12 +39,12 @@ void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size);
|
|||
// initiator resullt
|
||||
#define TRANSACTION_END 0
|
||||
#define TRANSACTION_NO_RESPONSE 0x1
|
||||
#define TRANSACTION_DATA_ERROR 0x2
|
||||
#define TRANSACTION_TYPE_ERROR 0x4
|
||||
#define TRANSACTION_DATA_ERROR 0x2
|
||||
#define TRANSACTION_TYPE_ERROR 0x4
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void);
|
||||
int soft_serial_transaction(void);
|
||||
#else
|
||||
int soft_serial_transaction(int sstd_index);
|
||||
int soft_serial_transaction(int sstd_index);
|
||||
#endif
|
||||
|
||||
// target status
|
||||
|
@ -58,5 +58,5 @@ int soft_serial_transaction(int sstd_index);
|
|||
// or TRANSACTION_ACCEPTED
|
||||
#define TRANSACTION_ACCEPTED 0x8
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_get_and_clean_status(int sstd_index);
|
||||
int soft_serial_get_and_clean_status(int sstd_index);
|
||||
#endif
|
||||
|
|
|
@ -7,87 +7,75 @@
|
|||
#include "quantum.h"
|
||||
|
||||
#ifdef EE_HANDS
|
||||
# include "tmk_core/common/eeprom.h"
|
||||
# include "eeconfig.h"
|
||||
# include "tmk_core/common/eeprom.h"
|
||||
# include "eeconfig.h"
|
||||
#endif
|
||||
|
||||
#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
|
||||
#include "rgblight.h"
|
||||
# include "rgblight.h"
|
||||
#endif
|
||||
|
||||
volatile bool isLeftHand = true;
|
||||
|
||||
__attribute__((weak))
|
||||
bool is_keyboard_left(void) {
|
||||
#if defined(SPLIT_HAND_PIN)
|
||||
__attribute__((weak)) bool is_keyboard_left(void) {
|
||||
#if defined(SPLIT_HAND_PIN)
|
||||
// Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand
|
||||
setPinInput(SPLIT_HAND_PIN);
|
||||
return readPin(SPLIT_HAND_PIN);
|
||||
#elif defined(EE_HANDS)
|
||||
#elif defined(EE_HANDS)
|
||||
return eeprom_read_byte(EECONFIG_HANDEDNESS);
|
||||
#elif defined(MASTER_RIGHT)
|
||||
#elif defined(MASTER_RIGHT)
|
||||
return !is_keyboard_master();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return is_keyboard_master();
|
||||
return is_keyboard_master();
|
||||
}
|
||||
|
||||
__attribute__((weak))
|
||||
bool is_keyboard_master(void)
|
||||
{
|
||||
__attribute__((weak)) bool is_keyboard_master(void) {
|
||||
#ifdef __AVR__
|
||||
static enum { UNKNOWN, MASTER, SLAVE } usbstate = UNKNOWN;
|
||||
static enum { UNKNOWN, MASTER, SLAVE } usbstate = UNKNOWN;
|
||||
|
||||
// only check once, as this is called often
|
||||
if (usbstate == UNKNOWN)
|
||||
{
|
||||
USBCON |= (1 << OTGPADE); // enables VBUS pad
|
||||
wait_us(5);
|
||||
// only check once, as this is called often
|
||||
if (usbstate == UNKNOWN) {
|
||||
USBCON |= (1 << OTGPADE); // enables VBUS pad
|
||||
wait_us(5);
|
||||
|
||||
usbstate = (USBSTA & (1 << VBUS)) ? MASTER : SLAVE; // checks state of VBUS
|
||||
}
|
||||
usbstate = (USBSTA & (1 << VBUS)) ? MASTER : SLAVE; // checks state of VBUS
|
||||
}
|
||||
|
||||
return (usbstate == MASTER);
|
||||
return (usbstate == MASTER);
|
||||
#else
|
||||
return true;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void keyboard_master_setup(void) {
|
||||
#if defined(USE_I2C) || defined(EH)
|
||||
#ifdef SSD1306OLED
|
||||
matrix_master_OLED_init ();
|
||||
#endif
|
||||
# ifdef SSD1306OLED
|
||||
matrix_master_OLED_init();
|
||||
# endif
|
||||
#endif
|
||||
transport_master_init();
|
||||
transport_master_init();
|
||||
}
|
||||
|
||||
static void keyboard_slave_setup(void)
|
||||
{
|
||||
transport_slave_init();
|
||||
}
|
||||
static void keyboard_slave_setup(void) { transport_slave_init(); }
|
||||
|
||||
// this code runs before the usb and keyboard is initialized
|
||||
void matrix_setup(void)
|
||||
{
|
||||
isLeftHand = is_keyboard_left();
|
||||
void matrix_setup(void) {
|
||||
isLeftHand = is_keyboard_left();
|
||||
|
||||
#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
|
||||
uint8_t num_rgb_leds_split[2] = RGBLED_SPLIT;
|
||||
if (isLeftHand) {
|
||||
rgblight_set_clipping_range(0, num_rgb_leds_split[0]);
|
||||
}
|
||||
else {
|
||||
rgblight_set_clipping_range(num_rgb_leds_split[0], num_rgb_leds_split[1]);
|
||||
}
|
||||
uint8_t num_rgb_leds_split[2] = RGBLED_SPLIT;
|
||||
if (isLeftHand) {
|
||||
rgblight_set_clipping_range(0, num_rgb_leds_split[0]);
|
||||
} else {
|
||||
rgblight_set_clipping_range(num_rgb_leds_split[0], num_rgb_leds_split[1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (is_keyboard_master())
|
||||
{
|
||||
keyboard_master_setup();
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboard_slave_setup();
|
||||
}
|
||||
if (is_keyboard_master()) {
|
||||
keyboard_master_setup();
|
||||
} else {
|
||||
keyboard_slave_setup();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
|
||||
extern volatile bool isLeftHand;
|
||||
|
||||
void matrix_master_OLED_init (void);
|
||||
void matrix_master_OLED_init(void);
|
||||
|
|
|
@ -8,101 +8,100 @@
|
|||
#define ROWS_PER_HAND (MATRIX_ROWS / 2)
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
# include "rgblight.h"
|
||||
# include "rgblight.h"
|
||||
#endif
|
||||
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
# include "backlight.h"
|
||||
# include "backlight.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENCODER_ENABLE
|
||||
# include "encoder.h"
|
||||
# include "encoder.h"
|
||||
static pin_t encoders_pad[] = ENCODERS_PAD_A;
|
||||
# define NUMBER_OF_ENCODERS (sizeof(encoders_pad)/sizeof(pin_t))
|
||||
# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t))
|
||||
#endif
|
||||
|
||||
#if defined(USE_I2C) || defined(EH)
|
||||
|
||||
# include "i2c_master.h"
|
||||
# include "i2c_slave.h"
|
||||
# include "i2c_master.h"
|
||||
# include "i2c_slave.h"
|
||||
|
||||
typedef struct _I2C_slave_buffer_t {
|
||||
matrix_row_t smatrix[ROWS_PER_HAND];
|
||||
uint8_t backlight_level;
|
||||
#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
rgblight_syncinfo_t rgblight_sync;
|
||||
#endif
|
||||
#ifdef ENCODER_ENABLE
|
||||
# endif
|
||||
# ifdef ENCODER_ENABLE
|
||||
uint8_t encoder_state[NUMBER_OF_ENCODERS];
|
||||
#endif
|
||||
# endif
|
||||
} I2C_slave_buffer_t;
|
||||
|
||||
static I2C_slave_buffer_t * const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
|
||||
static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
|
||||
|
||||
# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
|
||||
# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
|
||||
# define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix)
|
||||
# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
|
||||
# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
|
||||
# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
|
||||
# define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix)
|
||||
# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
|
||||
|
||||
# define TIMEOUT 100
|
||||
# define TIMEOUT 100
|
||||
|
||||
# ifndef SLAVE_I2C_ADDRESS
|
||||
# define SLAVE_I2C_ADDRESS 0x32
|
||||
# endif
|
||||
# ifndef SLAVE_I2C_ADDRESS
|
||||
# define SLAVE_I2C_ADDRESS 0x32
|
||||
# endif
|
||||
|
||||
// Get rows from other half over i2c
|
||||
bool transport_master(matrix_row_t matrix[]) {
|
||||
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, sizeof(i2c_buffer->smatrix), TIMEOUT);
|
||||
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, sizeof(i2c_buffer->smatrix), TIMEOUT);
|
||||
|
||||
// write backlight info
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0;
|
||||
if (level != i2c_buffer->backlight_level) {
|
||||
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) {
|
||||
i2c_buffer->backlight_level = level;
|
||||
// write backlight info
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0;
|
||||
if (level != i2c_buffer->backlight_level) {
|
||||
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) {
|
||||
i2c_buffer->backlight_level = level;
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
if (rgblight_get_change_flags()) {
|
||||
rgblight_syncinfo_t rgblight_sync;
|
||||
rgblight_get_syncinfo(&rgblight_sync);
|
||||
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START,
|
||||
(void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) {
|
||||
rgblight_clear_change_flags();
|
||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
if (rgblight_get_change_flags()) {
|
||||
rgblight_syncinfo_t rgblight_sync;
|
||||
rgblight_get_syncinfo(&rgblight_sync);
|
||||
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) {
|
||||
rgblight_clear_change_flags();
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef ENCODER_ENABLE
|
||||
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT);
|
||||
encoder_update_raw(i2c_buffer->encoder_state);
|
||||
# endif
|
||||
# ifdef ENCODER_ENABLE
|
||||
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT);
|
||||
encoder_update_raw(i2c_buffer->encoder_state);
|
||||
# endif
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void transport_slave(matrix_row_t matrix[]) {
|
||||
// Copy matrix to I2C buffer
|
||||
memcpy((void*)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix));
|
||||
// Copy matrix to I2C buffer
|
||||
memcpy((void *)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix));
|
||||
|
||||
// Read Backlight Info
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
backlight_set(i2c_buffer->backlight_level);
|
||||
# endif
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
backlight_set(i2c_buffer->backlight_level);
|
||||
# endif
|
||||
|
||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
// Update the RGB with the new data
|
||||
if (i2c_buffer->rgblight_sync.status.change_flags != 0) {
|
||||
rgblight_update_sync(&i2c_buffer->rgblight_sync, false);
|
||||
i2c_buffer->rgblight_sync.status.change_flags = 0;
|
||||
}
|
||||
# endif
|
||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
// Update the RGB with the new data
|
||||
if (i2c_buffer->rgblight_sync.status.change_flags != 0) {
|
||||
rgblight_update_sync(&i2c_buffer->rgblight_sync, false);
|
||||
i2c_buffer->rgblight_sync.status.change_flags = 0;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef ENCODER_ENABLE
|
||||
encoder_state_raw(i2c_buffer->encoder_state);
|
||||
# endif
|
||||
# ifdef ENCODER_ENABLE
|
||||
encoder_state_raw(i2c_buffer->encoder_state);
|
||||
# endif
|
||||
}
|
||||
|
||||
void transport_master_init(void) { i2c_init(); }
|
||||
|
@ -111,25 +110,25 @@ void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); }
|
|||
|
||||
#else // USE_SERIAL
|
||||
|
||||
# include "serial.h"
|
||||
# include "serial.h"
|
||||
|
||||
typedef struct _Serial_s2m_buffer_t {
|
||||
// TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
|
||||
matrix_row_t smatrix[ROWS_PER_HAND];
|
||||
// TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
|
||||
matrix_row_t smatrix[ROWS_PER_HAND];
|
||||
|
||||
# ifdef ENCODER_ENABLE
|
||||
uint8_t encoder_state[NUMBER_OF_ENCODERS];
|
||||
# endif
|
||||
# ifdef ENCODER_ENABLE
|
||||
uint8_t encoder_state[NUMBER_OF_ENCODERS];
|
||||
# endif
|
||||
|
||||
} Serial_s2m_buffer_t;
|
||||
|
||||
typedef struct _Serial_m2s_buffer_t {
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
uint8_t backlight_level;
|
||||
# endif
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
uint8_t backlight_level;
|
||||
# endif
|
||||
} Serial_m2s_buffer_t;
|
||||
|
||||
#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
// When MCUs on both sides drive their respective RGB LED chains,
|
||||
// it is necessary to synchronize, so it is necessary to communicate RGB
|
||||
// information. In that case, define RGBLIGHT_SPLIT with info on the number
|
||||
|
@ -144,7 +143,7 @@ typedef struct _Serial_rgblight_t {
|
|||
|
||||
volatile Serial_rgblight_t serial_rgblight = {};
|
||||
uint8_t volatile status_rgblight = 0;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
|
||||
volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
|
||||
|
@ -152,102 +151,99 @@ uint8_t volatile status0 = 0;
|
|||
|
||||
enum serial_transaction_id {
|
||||
GET_SLAVE_MATRIX = 0,
|
||||
#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
PUT_RGBLIGHT,
|
||||
#endif
|
||||
# endif
|
||||
};
|
||||
|
||||
SSTD_t transactions[] = {
|
||||
[GET_SLAVE_MATRIX] = {
|
||||
(uint8_t *)&status0,
|
||||
sizeof(serial_m2s_buffer),
|
||||
(uint8_t *)&serial_m2s_buffer,
|
||||
sizeof(serial_s2m_buffer),
|
||||
(uint8_t *)&serial_s2m_buffer,
|
||||
},
|
||||
#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
[PUT_RGBLIGHT] = {
|
||||
(uint8_t *)&status_rgblight,
|
||||
sizeof(serial_rgblight),
|
||||
(uint8_t *)&serial_rgblight,
|
||||
0, NULL // no slave to master transfer
|
||||
},
|
||||
#endif
|
||||
[GET_SLAVE_MATRIX] =
|
||||
{
|
||||
(uint8_t *)&status0,
|
||||
sizeof(serial_m2s_buffer),
|
||||
(uint8_t *)&serial_m2s_buffer,
|
||||
sizeof(serial_s2m_buffer),
|
||||
(uint8_t *)&serial_s2m_buffer,
|
||||
},
|
||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
[PUT_RGBLIGHT] =
|
||||
{
|
||||
(uint8_t *)&status_rgblight, sizeof(serial_rgblight), (uint8_t *)&serial_rgblight, 0, NULL // no slave to master transfer
|
||||
},
|
||||
# endif
|
||||
};
|
||||
|
||||
void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
|
||||
|
||||
void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
|
||||
|
||||
#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||
|
||||
// rgblight synchronization information communication.
|
||||
|
||||
void transport_rgblight_master(void) {
|
||||
if (rgblight_get_change_flags()) {
|
||||
rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync);
|
||||
if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) {
|
||||
rgblight_clear_change_flags();
|
||||
if (rgblight_get_change_flags()) {
|
||||
rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync);
|
||||
if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) {
|
||||
rgblight_clear_change_flags();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void transport_rgblight_slave(void) {
|
||||
if (status_rgblight == TRANSACTION_ACCEPTED) {
|
||||
rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync,
|
||||
false);
|
||||
status_rgblight = TRANSACTION_END;
|
||||
}
|
||||
if (status_rgblight == TRANSACTION_ACCEPTED) {
|
||||
rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync, false);
|
||||
status_rgblight = TRANSACTION_END;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#define transport_rgblight_master()
|
||||
#define transport_rgblight_slave()
|
||||
#endif
|
||||
# else
|
||||
# define transport_rgblight_master()
|
||||
# define transport_rgblight_slave()
|
||||
# endif
|
||||
|
||||
bool transport_master(matrix_row_t matrix[]) {
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
if (soft_serial_transaction() != TRANSACTION_END) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
transport_rgblight_master();
|
||||
if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
# ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
if (soft_serial_transaction() != TRANSACTION_END) {
|
||||
return false;
|
||||
}
|
||||
# else
|
||||
transport_rgblight_master();
|
||||
if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) {
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
|
||||
// TODO: if MATRIX_COLS > 8 change to unpack()
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
matrix[i] = serial_s2m_buffer.smatrix[i];
|
||||
}
|
||||
// TODO: if MATRIX_COLS > 8 change to unpack()
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
matrix[i] = serial_s2m_buffer.smatrix[i];
|
||||
}
|
||||
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
// Write backlight level for slave to read
|
||||
serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0;
|
||||
# endif
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
// Write backlight level for slave to read
|
||||
serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0;
|
||||
# endif
|
||||
|
||||
# ifdef ENCODER_ENABLE
|
||||
encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state);
|
||||
# endif
|
||||
# ifdef ENCODER_ENABLE
|
||||
encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state);
|
||||
# endif
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void transport_slave(matrix_row_t matrix[]) {
|
||||
transport_rgblight_slave();
|
||||
// TODO: if MATRIX_COLS > 8 change to pack()
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
serial_s2m_buffer.smatrix[i] = matrix[i];
|
||||
}
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
backlight_set(serial_m2s_buffer.backlight_level);
|
||||
# endif
|
||||
|
||||
# ifdef ENCODER_ENABLE
|
||||
encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state);
|
||||
# endif
|
||||
transport_rgblight_slave();
|
||||
// TODO: if MATRIX_COLS > 8 change to pack()
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
serial_s2m_buffer.smatrix[i] = matrix[i];
|
||||
}
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
backlight_set(serial_m2s_buffer.backlight_level);
|
||||
# endif
|
||||
|
||||
# ifdef ENCODER_ENABLE
|
||||
encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state);
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue