diff options
Diffstat (limited to 'keyboards/ai03/orbit')
-rw-r--r-- | keyboards/ai03/orbit/config.h | 13 | ||||
-rw-r--r-- | keyboards/ai03/orbit/keymaps/default/keymap.c | 16 | ||||
-rw-r--r-- | keyboards/ai03/orbit/matrix.c | 328 | ||||
-rw-r--r-- | keyboards/ai03/orbit/orbit.c | 270 | ||||
-rw-r--r-- | keyboards/ai03/orbit/orbit.h | 17 | ||||
-rw-r--r-- | keyboards/ai03/orbit/readme.md | 6 | ||||
-rw-r--r-- | keyboards/ai03/orbit/rules.mk | 10 | ||||
-rw-r--r-- | keyboards/ai03/orbit/serial.c | 545 | ||||
-rw-r--r-- | keyboards/ai03/orbit/serial.h | 62 | ||||
-rw-r--r-- | keyboards/ai03/orbit/split_flags.c | 5 | ||||
-rw-r--r-- | keyboards/ai03/orbit/split_flags.h | 15 | ||||
-rw-r--r-- | keyboards/ai03/orbit/split_util.c | 87 | ||||
-rw-r--r-- | keyboards/ai03/orbit/split_util.h | 10 | ||||
-rw-r--r-- | keyboards/ai03/orbit/transport.c | 238 | ||||
-rw-r--r-- | keyboards/ai03/orbit/transport.h | 42 |
15 files changed, 115 insertions, 1549 deletions
diff --git a/keyboards/ai03/orbit/config.h b/keyboards/ai03/orbit/config.h index 9ad384c8ff..0e4f4c3baf 100644 --- a/keyboards/ai03/orbit/config.h +++ b/keyboards/ai03/orbit/config.h @@ -44,13 +44,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define MATRIX_COL_PINS { C7, B4, D7, D6, D4, F1, F0 } #define MATRIX_ROW_PINS_RIGHT { B6, B5, B4, D7, E6 } #define MATRIX_COL_PINS_RIGHT { D4, D6, F1, F0, F4, F5, C6 } - -#define SPLIT_HAND_PIN D5 - -//#define USE_I2C - -#define SELECT_SOFT_SERIAL_SPEED 1 - #define UNUSED_PINS /* COL2ROW, ROW2COL */ @@ -60,6 +53,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. * Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN. */ #define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6 +#define SELECT_SOFT_SERIAL_SPEED 1 + +#define SPLIT_LED_STATE_ENABLE +#define SPLIT_LAYER_STATE_ENABLE + +#define SPLIT_HAND_PIN D5 #define BACKLIGHT_PIN B7 // #define BACKLIGHT_BREATHING diff --git a/keyboards/ai03/orbit/keymaps/default/keymap.c b/keyboards/ai03/orbit/keymaps/default/keymap.c index 6d4eef27c7..0c93f04897 100644 --- a/keyboards/ai03/orbit/keymaps/default/keymap.c +++ b/keyboards/ai03/orbit/keymaps/default/keymap.c @@ -48,25 +48,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { bool process_record_user(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case MANUAL: - if (record->event.pressed) - { - // Keypress + if (record->event.pressed) { SEND_STRING("https://kb.ai03.me/redir/orbit"); - } - else - { - // Key release } break; case DBLZERO: - if (record->event.pressed) - { - // Keypress + if (record->event.pressed) { SEND_STRING("00"); - } - else - { - // Key release } break; } diff --git a/keyboards/ai03/orbit/matrix.c b/keyboards/ai03/orbit/matrix.c deleted file mode 100644 index b8e3296686..0000000000 --- a/keyboards/ai03/orbit/matrix.c +++ /dev/null @@ -1,328 +0,0 @@ -/* -Copyright 2012 Jun Wako <wakojun@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -/* - * scan matrix - */ -#include <stdint.h> -#include <stdbool.h> -#include "wait.h" -#include "util.h" -#include "matrix.h" -#include "split_util.h" -#include "config.h" -#include "split_flags.h" -#include "quantum.h" -#include "debounce.h" -#include "transport.h" - -#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) -#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) -#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) -#endif - -#define ERROR_DISCONNECT_COUNT 5 - -//#define ROWS_PER_HAND (MATRIX_ROWS / 2) - -#ifdef DIRECT_PINS -static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS; -#else -static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; -static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; -#endif - -/* matrix state(1:on, 0:off) */ -static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t raw_matrix[ROWS_PER_HAND]; - -// row offsets for each hand -uint8_t thisHand, thatHand; - -// user-defined overridable functions - -__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); } - -__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } - -__attribute__((weak)) void matrix_init_user(void) {} - -__attribute__((weak)) void matrix_scan_user(void) {} - -__attribute__((weak)) void matrix_slave_scan_user(void) {} - -// helper functions - -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; -} - -inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); } - -inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } - -void matrix_print(void) { - print_matrix_header(); - - for (uint8_t row = 0; row < MATRIX_ROWS; row++) { - print_hex8(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; -} - -// matrix code - -#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); - } - } - } -} - -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; - - 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]); -} - -#elif (DIODE_DIRECTION == COL2ROW) - -static void select_row(uint8_t 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]); - } -} - -static void init_pins(void) { - 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]; - - // 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); - - // 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); - - 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]); -} - -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]); - } -} - -static void init_pins(void) { - 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; - - // 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]; - - // 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; - } - } - - // Unselect col - unselect_col(current_col); - - return matrix_changed; -} - -#endif - -void matrix_init(void) { - debug_enable = true; - debug_matrix = true; - debug_mouse = true; - - // Set pinout for right half if pinout for that half is defined - if (!isLeftHand) { -#ifdef MATRIX_ROW_PINS_RIGHT - const uint8_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 uint8_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; - - // initialize key pins - init_pins(); - - // initialize matrix state: all keys off - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - matrix[i] = 0; - } - - debounce_init(ROWS_PER_HAND); - - matrix_init_quantum(); -} - -uint8_t _matrix_scan(void) { - 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); - } -#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); - } -#endif - - debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed); - - return 1; -} - -uint8_t matrix_scan(void) { - uint8_t ret = _matrix_scan(); - - if (is_keyboard_master()) { - static uint8_t 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; - } - } - } else { - error_count = 0; - } - - matrix_scan_quantum(); - } else { - transport_slave(matrix + thisHand); - matrix_slave_scan_user(); - } - - return ret; -} diff --git a/keyboards/ai03/orbit/orbit.c b/keyboards/ai03/orbit/orbit.c index 97553e318a..5097f9cd90 100644 --- a/keyboards/ai03/orbit/orbit.c +++ b/keyboards/ai03/orbit/orbit.c @@ -15,196 +15,124 @@ */ #include "orbit.h" #include "split_util.h" -#include "transport.h" +void led_init_ports(void) { + // Initialize indicator LEDs to output + if (isLeftHand) { + setPinOutput(C6); + setPinOutput(B6); + setPinOutput(B5); + } else { + setPinOutput(F6); + setPinOutput(F7); + setPinOutput(C7); + } + + set_layer_indicators(0); +} // Call led_toggle to set LEDs easily // LED IDs: -// +// // (LEFT) 0 1 2 | 3 4 5 (RIGHT) - -void led_toggle(int id, bool on) { - - if (isLeftHand) { - switch(id) { - case 0: - // Left hand C6 - if (on) - //PORTC |= (1<<6); - writePinHigh(C6); - else - //PORTC &= ~(1<<6); - writePinLow(C6); - break; - case 1: - // Left hand B6 - if (on) - //PORTB |= (1<<6); - writePinHigh(B6); - else - //PORTB &= ~(1<<6); - writePinLow(B6); - break; - case 2: - // Left hand B5 - if (on) - //PORTB |= (1<<5); - writePinHigh(B5); - else - //PORTB &= ~(1<<5); - writePinLow(B5); - break; - default: - break; - } - } else { - switch(id) { - case 3: - // Right hand F6 - if (on) - //PORTF |= (1<<6); - writePinHigh(F6); - else - //PORTF &= ~(1<<6); - writePinLow(F6); - break; - case 4: - // Right hand F7 - if (on) - //PORTF |= (1<<7); - writePinHigh(F7); - else - //PORTF &= ~(1<<7); - writePinLow(F7); - break; - case 5: - // Right hand C7 - if (on) - //PORTC |= (1<<7); - writePinHigh(C7); - else - //PORTC &= ~(1<<7); - writePinLow(C7); - break; - default: - break; - } - } +void led_toggle(uint8_t id, bool on) { + if (isLeftHand) { + switch (id) { + case 0: + // Left hand C6 + writePin(C6, on); + break; + case 1: + // Left hand B6 + writePin(B6, on); + break; + case 2: + // Left hand B5 + writePin(B5, on); + break; + default: + break; + } + } else { + switch (id) { + case 3: + // Right hand F6 + writePin(F6, on); + break; + case 4: + // Right hand F7 + writePin(F7, on); + break; + case 5: + // Right hand C7 + writePin(C7, on); + break; + default: + break; + } + } } // Set all LEDs at once using an array of 6 booleans // LED IDs: -// +// // (LEFT) 0 1 2 | 3 4 5 (RIGHT) -// +// // Ex. set_all_leds({ false, false, false, true, true, true }) would turn off left hand, turn on right hand void set_all_leds(bool leds[6]) { - for (int i = 0; i < 6; i++) { - led_toggle(i, leds[i]); - } + for (int i = 0; i < 6; i++) { + led_toggle(i, leds[i]); + } } void set_layer_indicators(uint8_t layer) { - - switch (layer) - { - case 0: - led_toggle(0, true); - led_toggle(1, false); - led_toggle(2, false); - break; - case 1: - led_toggle(0, true); - led_toggle(1, true); - led_toggle(2, false); - break; - case 2: - led_toggle(0, true); - led_toggle(1, true); - led_toggle(2, true); - break; - case 3: - led_toggle(0, false); - led_toggle(1, true); - led_toggle(2, true); - break; - case 4: - led_toggle(0, false); - led_toggle(1, false); - led_toggle(2, true); - break; - default: - led_toggle(0, true); - led_toggle(1, false); - led_toggle(2, true); - break; - } - + switch (layer) { + case 0: + led_toggle(0, true); + led_toggle(1, false); + led_toggle(2, false); + break; + case 1: + led_toggle(0, true); + led_toggle(1, true); + led_toggle(2, false); + break; + case 2: + led_toggle(0, true); + led_toggle(1, true); + led_toggle(2, true); + break; + case 3: + led_toggle(0, false); + led_toggle(1, true); + led_toggle(2, true); + break; + case 4: + led_toggle(0, false); + led_toggle(1, false); + led_toggle(2, true); + break; + default: + led_toggle(0, true); + led_toggle(1, false); + led_toggle(2, true); + break; + } } -void matrix_init_kb(void) { - // put your keyboard start-up code here - // runs once when the firmware starts up - - // Initialize indicator LEDs to output - if (isLeftHand) - { - setPinOutput(C6); - setPinOutput(B6); - setPinOutput(B5); - //DDRC |= (1<<6); - //DDRB |= (1<<6); - //DDRB |= (1<<5); - } - else - { - setPinOutput(F6); - setPinOutput(F7); - setPinOutput(C7); - //DDRF |= (1<<6); - //DDRF |= (1<<7); - //DDRC |= (1<<7); - } - - set_layer_indicators(0); - - matrix_init_user(); +bool led_update_kb(led_t led_state) { + bool res = led_update_user(led_state); + if (res) { + led_toggle(3, led_state.num_lock); + led_toggle(4, led_state.caps_lock); + led_toggle(5, led_state.scroll_lock); + } + return res; } -void led_set_kb(uint8_t usb_led) { - // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here - - if (is_keyboard_master()) { - - serial_m2s_buffer.nlock_led = IS_LED_ON(usb_led, USB_LED_NUM_LOCK); - serial_m2s_buffer.clock_led = IS_LED_ON(usb_led, USB_LED_CAPS_LOCK); - serial_m2s_buffer.slock_led = IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK); - - led_toggle(3, IS_LED_ON(usb_led, USB_LED_NUM_LOCK)); - led_toggle(4, IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)); - led_toggle(5, IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)); - - } - - led_set_user(usb_led); -} +layer_state_t layer_state_set_kb(layer_state_t state) { + set_layer_indicators(get_highest_layer(state)); -uint32_t layer_state_set_kb(uint32_t state) { - - if (is_keyboard_master()) - { - serial_m2s_buffer.current_layer = biton32(state); - - // If left half, do the LED toggle thing - if (isLeftHand) - { - set_layer_indicators(biton32(state)); - } - - } - // NOTE: Do not set slave LEDs here. - // This is not called on slave - - return layer_state_set_user(state); + return layer_state_set_user(state); } diff --git a/keyboards/ai03/orbit/orbit.h b/keyboards/ai03/orbit/orbit.h index 39f1ebb0e3..7f3b1aca32 100644 --- a/keyboards/ai03/orbit/orbit.h +++ b/keyboards/ai03/orbit/orbit.h @@ -18,6 +18,8 @@ #include "quantum.h" +#define XXX KC_NO + /* This a shortcut to help you visually see your layout. * * The first section contains all of the arguments representing the physical @@ -26,17 +28,6 @@ * The second converts the arguments into a two-dimensional array which * represents the switch matrix. */ - -#ifdef USE_I2C -#include <stddef.h> -#ifdef __AVR__ - #include <avr/io.h> - #include <avr/interrupt.h> -#endif -#endif - -#define XXX KC_NO - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, L06, R00, R01, R02, R03, R04, R05, R06, \ L10, L11, L12, L13, L14, L15, L16, R10, R11, R12, R13, R14, R15, R16, \ @@ -56,6 +47,6 @@ { R40, R41, R42, R43, R44, R45, XXX } \ } -extern void led_toggle(int id, bool on); +void led_toggle(uint8_t id, bool on); void set_all_leds(bool leds[6]); -extern void set_layer_indicators(uint8_t layer); +void set_layer_indicators(uint8_t layer); diff --git a/keyboards/ai03/orbit/readme.md b/keyboards/ai03/orbit/readme.md index 58ba2079d5..0c320929b6 100644 --- a/keyboards/ai03/orbit/readme.md +++ b/keyboards/ai03/orbit/readme.md @@ -4,9 +4,9 @@ A split ergonomic keyboard project. -Keyboard Maintainer: [ai03](https://github.com/ai03-2725) -Hardware Supported: The [Orbit PCB](https://github.com/ai03-2725/Orbit) -Hardware Availability: [This repository](https://github.com/ai03-2725/Orbit) has PCB files. Case group buy orders are currently closed. +* Keyboard Maintainer: [ai03](https://github.com/ai03-2725) +* Hardware Supported: The [Orbit PCB](https://github.com/ai03-2725/Orbit) +* Hardware Availability: [This repository](https://github.com/ai03-2725/Orbit) has PCB files. Case group buy orders are currently closed. Make example for this keyboard (after setting up your build environment): diff --git a/keyboards/ai03/orbit/rules.mk b/keyboards/ai03/orbit/rules.mk index 5e7aa75e35..8d01319972 100644 --- a/keyboards/ai03/orbit/rules.mk +++ b/keyboards/ai03/orbit/rules.mk @@ -17,12 +17,4 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -USE_I2C = no # I2C for split communication -CUSTOM_MATRIX = yes # For providing custom matrix.c (in this case, override regular matrix.c with split matrix.c) -# SPLIT_KEYBOARD = yes # Split keyboard flag disabled as manual edits had to be done to the split common files - -SRC += split_util.c \ - split_flags.c \ - serial.c \ - transport.c \ - matrix.c +SPLIT_KEYBOARD = yes # Split keyboard flag disabled as manual edits had to be done to the split common files diff --git a/keyboards/ai03/orbit/serial.c b/keyboards/ai03/orbit/serial.c deleted file mode 100644 index 636dfa0906..0000000000 --- a/keyboards/ai03/orbit/serial.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - * WARNING: be careful changing this code, it is very timing dependent - * - * 2018-10-28 checked - * avr-gcc 4.9.2 - * avr-gcc 5.4.0 - * avr-gcc 7.3.0 - */ - -#ifndef F_CPU -#define F_CPU 16000000 -#endif - -#include <avr/io.h> -#include <avr/interrupt.h> -#include <util/delay.h> -#include <stddef.h> -#include <stdbool.h> -#include "serial.h" - -#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 - - #if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3 - #define SERIAL_PIN_DDR DDRD - #define SERIAL_PIN_PORT PORTD - #define SERIAL_PIN_INPUT PIND - #if SOFT_SERIAL_PIN == D0 - #define SERIAL_PIN_MASK _BV(PD0) - #define EIMSK_BIT _BV(INT0) - #define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01))) - #define SERIAL_PIN_INTERRUPT INT0_vect - #elif SOFT_SERIAL_PIN == D1 - #define SERIAL_PIN_MASK _BV(PD1) - #define EIMSK_BIT _BV(INT1) - #define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11))) - #define SERIAL_PIN_INTERRUPT INT1_vect - #elif SOFT_SERIAL_PIN == D2 - #define SERIAL_PIN_MASK _BV(PD2) - #define EIMSK_BIT _BV(INT2) - #define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21))) - #define SERIAL_PIN_INTERRUPT INT2_vect - #elif SOFT_SERIAL_PIN == D3 - #define SERIAL_PIN_MASK _BV(PD3) - #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 SERIAL_PIN_DDR DDRE - #define SERIAL_PIN_PORT PORTE - #define SERIAL_PIN_INPUT PINE - #define SERIAL_PIN_MASK _BV(PE6) - #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 - -#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 - -#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 -// 0: about 189kbps (Experimental only) -// 1: about 137kbps (default) -// 2: about 75kbps -// 3: about 39kbps -// 4: about 26kbps -// 5: about 20kbps -#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 */ - -#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 - -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_half1(void) ALWAYS_INLINE; -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_output(void) ALWAYS_INLINE; -inline static -void serial_output(void) { - SERIAL_PIN_DDR |= SERIAL_PIN_MASK; -} - -// 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) { - SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK; - SERIAL_PIN_PORT |= SERIAL_PIN_MASK; -} - -inline static uint8_t serial_read_pin(void) ALWAYS_INLINE; -inline static -uint8_t serial_read_pin(void) { - return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); -} - -inline static void serial_low(void) ALWAYS_INLINE; -inline static -void serial_low(void) { - SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; -} - -inline static void serial_high(void) ALWAYS_INLINE; -inline static -void serial_high(void) { - SERIAL_PIN_PORT |= SERIAL_PIN_MASK; -} - -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; - Transaction_table_size = (uint8_t)sstd_table_size; - serial_input_with_pullup(); - - // Enable INT0-INT3,INT6 - EIMSK |= EIMSK_BIT; -#if SERIAL_PIN_MASK == _BV(PE6) - // Trigger on falling edge of INT6 - EICRB &= EICRx_BIT; -#else - // Trigger on falling edge of INT0-INT3 - EICRA &= EICRx_BIT; -#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()); -} - -// 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(); |