diff options
| author | James Churchill <pelrun@gmail.com> | 2019-03-13 03:23:28 +1000 |
|---|---|---|
| committer | Drashna Jaelre <drashna@live.com> | 2019-03-12 10:23:28 -0700 |
| commit | 37932c293c15011f883a91e91ee02631ead44a2e (patch) | |
| tree | f1b4b3b44f816240b06580658b42b3646f121025 /quantum | |
| parent | 25bb059e4e42ed2637202230ff3d8b765e1295cd (diff) | |
| download | qmk_firmware-37932c293c15011f883a91e91ee02631ead44a2e.tar.gz qmk_firmware-37932c293c15011f883a91e91ee02631ead44a2e.zip | |
Next set of split_common changes (#4974)
* Update split_common to use standard i2c drivers
* Eliminate RGB_DIRTY/BACKLIT_DIRTY
* Fix avr i2c_master error handling
* Fix i2c_slave addressing
* Remove unneeded timeout on i2c_stop()
* Fix RGB I2C transfers
* Remove incorrect comment
Diffstat (limited to 'quantum')
| -rw-r--r-- | quantum/keymap_common.c | 22 | ||||
| -rw-r--r-- | quantum/quantum.c | 30 | ||||
| -rw-r--r-- | quantum/quantum.h | 4 | ||||
| -rw-r--r-- | quantum/split_common/i2c.c | 184 | ||||
| -rw-r--r-- | quantum/split_common/i2c.h | 59 | ||||
| -rw-r--r-- | quantum/split_common/matrix.c | 1 | ||||
| -rw-r--r-- | quantum/split_common/split_flags.c | 5 | ||||
| -rw-r--r-- | quantum/split_common/split_flags.h | 15 | ||||
| -rw-r--r-- | quantum/split_common/split_util.c | 5 | ||||
| -rw-r--r-- | quantum/split_common/transport.c | 236 |
10 files changed, 85 insertions, 476 deletions
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 9d2d331ce..eef739a14 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c | |||
| @@ -29,10 +29,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 29 | #include "backlight.h" | 29 | #include "backlight.h" |
| 30 | #include "quantum.h" | 30 | #include "quantum.h" |
| 31 | 31 | ||
| 32 | #ifdef SPLIT_KEYBOARD | ||
| 33 | #include "split_flags.h" | ||
| 34 | #endif | ||
| 35 | |||
| 36 | #ifdef MIDI_ENABLE | 32 | #ifdef MIDI_ENABLE |
| 37 | #include "process_midi.h" | 33 | #include "process_midi.h" |
| 38 | #endif | 34 | #endif |
| @@ -138,39 +134,21 @@ action_t action_for_key(uint8_t layer, keypos_t key) | |||
| 138 | #ifdef BACKLIGHT_ENABLE | 134 | #ifdef BACKLIGHT_ENABLE |
| 139 | case BL_ON: | 135 | case BL_ON: |
| 140 | action.code = ACTION_BACKLIGHT_ON(); | 136 | action.code = ACTION_BACKLIGHT_ON(); |
| 141 | #ifdef SPLIT_KEYBOARD | ||
| 142 | BACKLIT_DIRTY = true; | ||
| 143 | #endif | ||
| 144 | break; | 137 | break; |
| 145 | case BL_OFF: | 138 | case BL_OFF: |
| 146 | action.code = ACTION_BACKLIGHT_OFF(); | 139 | action.code = ACTION_BACKLIGHT_OFF(); |
| 147 | #ifdef SPLIT_KEYBOARD | ||
| 148 | BACKLIT_DIRTY = true; | ||
| 149 | #endif | ||
| 150 | break; | 140 | break; |
| 151 | case BL_DEC: | 141 | case BL_DEC: |
| 152 | action.code = ACTION_BACKLIGHT_DECREASE(); | 142 | action.code = ACTION_BACKLIGHT_DECREASE(); |
| 153 | #ifdef SPLIT_KEYBOARD | ||
| 154 | BACKLIT_DIRTY = true; | ||
| 155 | #endif | ||
| 156 | break; | 143 | break; |
| 157 | case BL_INC: | 144 | case BL_INC: |
| 158 | action.code = ACTION_BACKLIGHT_INCREASE(); | 145 | action.code = ACTION_BACKLIGHT_INCREASE(); |
| 159 | #ifdef SPLIT_KEYBOARD | ||
| 160 | BACKLIT_DIRTY = true; | ||
| 161 | #endif | ||
| 162 | break; | 146 | break; |
| 163 | case BL_TOGG: | 147 | case BL_TOGG: |
| 164 | action.code = ACTION_BACKLIGHT_TOGGLE(); | 148 | action.code = ACTION_BACKLIGHT_TOGGLE(); |
| 165 | #ifdef SPLIT_KEYBOARD | ||
| 166 | BACKLIT_DIRTY = true; | ||
| 167 | #endif | ||
| 168 | break; | 149 | break; |
| 169 | case BL_STEP: | 150 | case BL_STEP: |
| 170 | action.code = ACTION_BACKLIGHT_STEP(); | 151 | action.code = ACTION_BACKLIGHT_STEP(); |
| 171 | #ifdef SPLIT_KEYBOARD | ||
| 172 | BACKLIT_DIRTY = true; | ||
| 173 | #endif | ||
| 174 | break; | 152 | break; |
| 175 | #endif | 153 | #endif |
| 176 | #ifdef SWAP_HANDS_ENABLE | 154 | #ifdef SWAP_HANDS_ENABLE |
diff --git a/quantum/quantum.c b/quantum/quantum.c index 46d404029..8316d1f06 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c | |||
| @@ -360,9 +360,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 360 | if (!record->event.pressed) { | 360 | if (!record->event.pressed) { |
| 361 | #endif | 361 | #endif |
| 362 | rgblight_toggle(); | 362 | rgblight_toggle(); |
| 363 | #ifdef SPLIT_KEYBOARD | ||
| 364 | RGB_DIRTY = true; | ||
| 365 | #endif | ||
| 366 | } | 363 | } |
| 367 | return false; | 364 | return false; |
| 368 | case RGB_MODE_FORWARD: | 365 | case RGB_MODE_FORWARD: |
| @@ -374,9 +371,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 374 | else { | 371 | else { |
| 375 | rgblight_step(); | 372 | rgblight_step(); |
| 376 | } | 373 | } |
| 377 | #ifdef SPLIT_KEYBOARD | ||
| 378 | RGB_DIRTY = true; | ||
| 379 | #endif | ||
| 380 | } | 374 | } |
| 381 | return false; | 375 | return false; |
| 382 | case RGB_MODE_REVERSE: | 376 | case RGB_MODE_REVERSE: |
| @@ -388,9 +382,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 388 | else { | 382 | else { |
| 389 | rgblight_step_reverse(); | 383 | rgblight_step_reverse(); |
| 390 | } | 384 | } |
| 391 | #ifdef SPLIT_KEYBOARD | ||
| 392 | RGB_DIRTY = true; | ||
| 393 | #endif | ||
| 394 | } | 385 | } |
| 395 | return false; | 386 | return false; |
| 396 | case RGB_HUI: | 387 | case RGB_HUI: |
| @@ -401,9 +392,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 401 | if (!record->event.pressed) { | 392 | if (!record->event.pressed) { |
| 402 | #endif | 393 | #endif |
| 403 | rgblight_increase_hue(); | 394 | rgblight_increase_hue(); |
| 404 | #ifdef SPLIT_KEYBOARD | ||
| 405 | RGB_DIRTY = true; | ||
| 406 | #endif | ||
| 407 | } | 395 | } |
| 408 | return false; | 396 | return false; |
| 409 | case RGB_HUD: | 397 | case RGB_HUD: |
| @@ -414,9 +402,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 414 | if (!record->event.pressed) { | 402 | if (!record->event.pressed) { |
| 415 | #endif | 403 | #endif |
| 416 | rgblight_decrease_hue(); | 404 | rgblight_decrease_hue(); |
| 417 | #ifdef SPLIT_KEYBOARD | ||
| 418 | RGB_DIRTY = true; | ||
| 419 | #endif | ||
| 420 | } | 405 | } |
| 421 | return false; | 406 | return false; |
| 422 | case RGB_SAI: | 407 | case RGB_SAI: |
| @@ -427,9 +412,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 427 | if (!record->event.pressed) { | 412 | if (!record->event.pressed) { |
| 428 | #endif | 413 | #endif |
| 429 | rgblight_increase_sat(); | 414 | rgblight_increase_sat(); |
| 430 | #ifdef SPLIT_KEYBOARD | ||
| 431 | RGB_DIRTY = true; | ||
| 432 | #endif | ||
| 433 | } | 415 | } |
| 434 | return false; | 416 | return false; |
| 435 | case RGB_SAD: | 417 | case RGB_SAD: |
| @@ -440,9 +422,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 440 | if (!record->event.pressed) { | 422 | if (!record->event.pressed) { |
| 441 | #endif | 423 | #endif |
| 442 | rgblight_decrease_sat(); | 424 | rgblight_decrease_sat(); |
| 443 | #ifdef SPLIT_KEYBOARD | ||
| 444 | RGB_DIRTY = true; | ||
| 445 | #endif | ||
| 446 | } | 425 | } |
| 447 | return false; | 426 | return false; |
| 448 | case RGB_VAI: | 427 | case RGB_VAI: |
| @@ -453,9 +432,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 453 | if (!record->event.pressed) { | 432 | if (!record->event.pressed) { |
| 454 | #endif | 433 | #endif |
| 455 | rgblight_increase_val(); | 434 | rgblight_increase_val(); |
| 456 | #ifdef SPLIT_KEYBOARD | ||
| 457 | RGB_DIRTY = true; | ||
| 458 | #endif | ||
| 459 | } | 435 | } |
| 460 | return false; | 436 | return false; |
| 461 | case RGB_VAD: | 437 | case RGB_VAD: |
| @@ -466,9 +442,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 466 | if (!record->event.pressed) { | 442 | if (!record->event.pressed) { |
| 467 | #endif | 443 | #endif |
| 468 | rgblight_decrease_val(); | 444 | rgblight_decrease_val(); |
| 469 | #ifdef SPLIT_KEYBOARD | ||
| 470 | RGB_DIRTY = true; | ||
| 471 | #endif | ||
| 472 | } | 445 | } |
| 473 | return false; | 446 | return false; |
| 474 | case RGB_SPI: | 447 | case RGB_SPI: |
| @@ -484,9 +457,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 484 | case RGB_MODE_PLAIN: | 457 | case RGB_MODE_PLAIN: |
| 485 | if (record->event.pressed) { | 458 | if (record->event.pressed) { |
| 486 | rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); | 459 | rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); |
| 487 | #ifdef SPLIT_KEYBOARD | ||
| 488 | RGB_DIRTY = true; | ||
| 489 | #endif | ||
| 490 | } | 460 | } |
| 491 | return false; | 461 | return false; |
| 492 | case RGB_MODE_BREATHE: | 462 | case RGB_MODE_BREATHE: |
diff --git a/quantum/quantum.h b/quantum/quantum.h index d2c5862f8..c12ac9ab8 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h | |||
| @@ -44,10 +44,6 @@ | |||
| 44 | #endif | 44 | #endif |
| 45 | #endif | 45 | #endif |
| 46 | 46 | ||
| 47 | #ifdef SPLIT_KEYBOARD | ||
| 48 | #include "split_flags.h" | ||
| 49 | #endif | ||
| 50 | |||
| 51 | #ifdef RGB_MATRIX_ENABLE | 47 | #ifdef RGB_MATRIX_ENABLE |
| 52 | #include "rgb_matrix.h" | 48 | #include "rgb_matrix.h" |
| 53 | #endif | 49 | #endif |
diff --git a/quantum/split_common/i2c.c b/quantum/split_common/i2c.c deleted file mode 100644 index 45e958b39..000000000 --- a/quantum/split_common/i2c.c +++ /dev/null | |||
| @@ -1,184 +0,0 @@ | |||
| 1 | #include <util/twi.h> | ||
| 2 | #include <avr/io.h> | ||
| 3 | #include <stdlib.h> | ||
| 4 | #include <avr/interrupt.h> | ||
| 5 | #include <util/twi.h> | ||
| 6 | #include <stdbool.h> | ||
| 7 | #include "i2c.h" | ||
| 8 | #include "split_flags.h" | ||
| 9 | |||
| 10 | // Limits the amount of we wait for any one i2c transaction. | ||
| 11 | // Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is | ||
| 12 | // 9 bits, a single transaction will take around 90μs to complete. | ||
| 13 | // | ||
| 14 | // (F_CPU/SCL_CLOCK) => # of μC cycles to transfer a bit | ||
| 15 | // poll loop takes at least 8 clock cycles to execute | ||
| 16 | #define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8 | ||
| 17 | |||
| 18 | #define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE) | ||
| 19 | |||
| 20 | volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; | ||
| 21 | |||
| 22 | static volatile uint8_t slave_buffer_pos; | ||
| 23 | static volatile bool slave_has_register_set = false; | ||
| 24 | |||
| 25 | // Wait for an i2c operation to finish | ||
| 26 | inline static | ||
| 27 | void i2c_delay(void) { | ||
| 28 | uint16_t lim = 0; | ||
| 29 | while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT) | ||
| 30 | lim++; | ||
| 31 | |||
| 32 | // easier way, but will wait slightly longer | ||
| 33 | // _delay_us(100); | ||
| 34 | } | ||
| 35 | |||
| 36 | // Setup twi to run at 100kHz | ||
| 37 | void i2c_master_init(void) { | ||
| 38 | // no prescaler | ||
| 39 | TWSR = 0; | ||
| 40 | // Set TWI clock frequency to SCL_CLOCK. Need TWBR>10. | ||
| 41 | // Check datasheets for more info. | ||
| 42 | TWBR = ((F_CPU/SCL_CLOCK)-16)/2; | ||
| 43 | } | ||
| 44 | |||
| 45 | // Start a transaction with the given i2c slave address. The direction of the | ||
| 46 | // transfer is set with I2C_READ and I2C_WRITE. | ||
| 47 | // returns: 0 => success | ||
| 48 | // 1 => error | ||
| 49 | uint8_t i2c_master_start(uint8_t address) { | ||
| 50 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA); | ||
| 51 | |||
| 52 | i2c_delay(); | ||
| 53 | |||
| 54 | // check that we started successfully | ||
| 55 | if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START)) | ||
| 56 | return 1; | ||
| 57 | |||
| 58 | TWDR = address; | ||
| 59 | TWCR = (1<<TWINT) | (1<<TWEN); | ||
| 60 | |||
| 61 | i2c_delay(); | ||
| 62 | |||
| 63 | if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) ) | ||
| 64 | return 1; // slave did not acknowledge | ||
| 65 | else | ||
| 66 | return 0; // success | ||
| 67 | } | ||
| 68 | |||
| 69 | |||
| 70 | // Finish the i2c transaction. | ||
| 71 | void i2c_master_stop(void) { | ||
| 72 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); | ||
| 73 | |||
| 74 | uint16_t lim = 0; | ||
| 75 | while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT) | ||
| 76 | lim++; | ||
| 77 | } | ||
| 78 | |||
| 79 | // Write one byte to the i2c slave. | ||
| 80 | // returns 0 => slave ACK | ||
| 81 | // 1 => slave NACK | ||
| 82 | uint8_t i2c_master_write(uint8_t data) { | ||
| 83 | TWDR = data; | ||
| 84 | TWCR = (1<<TWINT) | (1<<TWEN); | ||
| 85 | |||
| 86 | i2c_delay(); | ||
| 87 | |||
| 88 | // check if the slave acknowledged us | ||
| 89 | return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1; | ||
| 90 | } | ||
| 91 | |||
| 92 | uint8_t i2c_master_write_data(void *const TXdata, uint8_t dataLen) { | ||
| 93 | |||
| 94 | uint8_t *data = (uint8_t *)TXdata; | ||
| 95 | int err = 0; | ||
| 96 | |||
| 97 | for (int i = 0; i < dataLen; i++) { | ||
| 98 | err = i2c_master_write(data[i]); | ||
| 99 | |||
| 100 | if ( err ) | ||
| 101 | return err; | ||
| 102 | } | ||
| 103 | |||
| 104 | return err; | ||
| 105 | |||
| 106 | } | ||
| 107 | |||
| 108 | // Read one byte from the i2c slave. If ack=1 the slave is acknowledged, | ||
| 109 | // if ack=0 the acknowledge bit is not set. | ||
| 110 | // returns: byte read from i2c device | ||
| 111 | uint8_t i2c_master_read(int ack) { | ||
| 112 | TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA); | ||
| 113 | |||
| 114 | i2c_delay(); | ||
| 115 | return TWDR; | ||
| 116 | } | ||
| 117 | |||
| 118 | void i2c_reset_state(void) { | ||
| 119 | TWCR = 0; | ||
| 120 | } | ||
| 121 | |||
| 122 | void i2c_slave_init(uint8_t address) { | ||
| 123 | TWAR = address << 0; // slave i2c address | ||
| 124 | // TWEN - twi enable | ||
| 125 | // TWEA - enable address acknowledgement | ||
| 126 | // TWINT - twi interrupt flag | ||
| 127 | // TWIE - enable the twi interrupt | ||
| 128 | TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN); | ||
| 129 | } | ||
| 130 | |||
| 131 | ISR(TWI_vect); | ||
| 132 | |||
| 133 | ISR(TWI_vect) { | ||
| 134 | uint8_t ack = 1; | ||
| 135 | switch(TW_STATUS) { | ||
| 136 | case TW_SR_SLA_ACK: | ||
| 137 | // this device has been addressed as a slave receiver | ||
| 138 | slave_has_register_set = false; | ||
| 139 | break; | ||
| 140 | |||
| 141 | case TW_SR_DATA_ACK: | ||
| 142 | // this device has received data as a slave receiver | ||
| 143 | // The first byte that we receive in this transaction sets the location | ||
| 144 | // of the read/write location of the slaves memory that it exposes over | ||
| 145 | // i2c. After that, bytes will be written at slave_buffer_pos, incrementing | ||
| 146 | // slave_buffer_pos after each write. | ||
| 147 | if(!slave_has_register_set) { | ||
| 148 | slave_buffer_pos = TWDR; | ||
| 149 | // don't acknowledge the master if this memory loctaion is out of bounds | ||
| 150 | if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) { | ||
| 151 | ack = 0; | ||
| 152 | slave_buffer_pos = 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | slave_has_register_set = true; | ||
| 156 | } else { | ||
| 157 | i2c_slave_buffer[slave_buffer_pos] = TWDR; | ||
| 158 | |||
| 159 | if ( slave_buffer_pos == I2C_BACKLIT_START) { | ||
| 160 | BACKLIT_DIRTY = true; | ||
| 161 | } else if ( slave_buffer_pos == (I2C_RGB_START+3)) { | ||
| 162 | RGB_DIRTY = true; | ||
| 163 | } | ||
| 164 | |||
| 165 | BUFFER_POS_INC(); | ||
| 166 | } | ||
| 167 | break; | ||
| 168 | |||
| 169 | case TW_ST_SLA_ACK: | ||
| 170 | case TW_ST_DATA_ACK: | ||
| 171 | // master has addressed this device as a slave transmitter and is | ||
| 172 | // requesting data. | ||
| 173 | TWDR = i2c_slave_buffer[slave_buffer_pos]; | ||
| 174 | BUFFER_POS_INC(); | ||
| 175 | break; | ||
| 176 | |||
| 177 | case TW_BUS_ERROR: // something went wrong, reset twi state | ||
| 178 | TWCR = 0; | ||
| 179 | default: | ||
| 180 | break; | ||
| 181 | } | ||
| 182 | // Reset everything, so we are ready for the next TWI interrupt | ||
| 183 | TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN); | ||
| 184 | } | ||
diff --git a/quantum/split_common/i2c.h b/quantum/split_common/i2c.h deleted file mode 100644 index 91e8e96f4..000000000 --- a/quantum/split_common/i2c.h +++ /dev/null | |||
| @@ -1,59 +0,0 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <stdint.h> | ||
| 4 | |||
| 5 | #ifndef F_CPU | ||
| 6 | #define F_CPU 16000000UL | ||
| 7 | #endif | ||
| 8 | |||
| 9 | #define I2C_READ 1 | ||
| 10 | #define I2C_WRITE 0 | ||
| 11 | |||
| 12 | #define I2C_ACK 1 | ||
| 13 | #define I2C_NACK 0 | ||
| 14 | |||
| 15 | // Address location defines (Keymap should be last, as it's size is dynamic) | ||
| 16 | #define I2C_BACKLIT_START 0x00 | ||
| 17 | // Need 4 bytes for RGB (32 bit) | ||
| 18 | #define I2C_RGB_START 0x01 | ||
| 19 | #define I2C_KEYMAP_START 0x06 | ||
| 20 | |||
| 21 | // Slave buffer (8bit per) | ||
| 22 | // Rows per hand + backlit space + rgb space | ||
| 23 | // TODO : Make this dynamically sized | ||
| 24 | #define SLAVE_BUFFER_SIZE 0x20 | ||
| 25 | |||
| 26 | // i2c SCL clock frequency | ||
| 27 | #ifndef SCL_CLOCK | ||
| 28 | #define SCL_CLOCK 100000L | ||
| 29 | #endif | ||
| 30 | |||
| 31 | // Support 8bits right now (8 cols) will need to edit to take higher (code exists in delta split?) | ||
| 32 | extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; | ||
| 33 | |||
| 34 | void i2c_master_init(void); | ||
| 35 | uint8_t i2c_master_start(uint8_t address); | ||
| 36 | void i2c_master_stop(void); | ||
| 37 | uint8_t i2c_master_write(uint8_t data); | ||
| 38 | uint8_t i2c_master_write_data(void *const TXdata, uint8_t dataLen); | ||
| 39 | uint8_t i2c_master_read(int); | ||
| 40 | void i2c_reset_state(void); | ||
| 41 | void i2c_slave_init(uint8_t address); | ||
| 42 | |||
| 43 | |||
| 44 | static inline unsigned char i2c_start_read(unsigned char addr) { | ||
| 45 | return i2c_master_start((addr << 1) | I2C_READ); | ||
| 46 | } | ||
| 47 | |||
| 48 | static inline unsigned char i2c_start_write(unsigned char addr) { | ||
| 49 | return i2c_master_start((addr << 1) | I2C_WRITE); | ||
| 50 | } | ||
| 51 | |||
| 52 | // from SSD1306 scrips | ||
| 53 | extern unsigned char i2c_rep_start(unsigned char addr); | ||
| 54 | extern void i2c_start_wait(unsigned char addr); | ||
| 55 | extern unsigned char i2c_readAck(void); | ||
| 56 | extern unsigned char i2c_readNak(void); | ||
| 57 | extern unsigned char i2c_read(unsigned char ack); | ||
| 58 | |||
| 59 | #define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); | ||
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index f2a277c69..dcb96254f 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c | |||
| @@ -25,7 +25,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 25 | #include "matrix.h" | 25 | #include "matrix.h" |
| 26 | #include "split_util.h" | 26 | #include "split_util.h" |
| 27 | #include "config.h" | 27 | #include "config.h" |
| 28 | #include "split_flags.h" | ||
| 29 | #include "quantum.h" | 28 | #include "quantum.h" |
| 30 | #include "debounce.h" | 29 | #include "debounce.h" |
| 31 | #include "transport.h" | 30 | #include "transport.h" |
diff --git a/quantum/split_common/split_flags.c b/quantum/split_common/split_flags.c deleted file mode 100644 index 1f5825d65..000000000 --- a/quantum/split_common/split_flags.c +++ /dev/null | |||
| @@ -1,5 +0,0 @@ | |||
| 1 | #include "split_flags.h" | ||
| 2 | |||
| 3 | volatile bool RGB_DIRTY = false; | ||
| 4 | |||
| 5 | volatile bool BACKLIT_DIRTY = false; \ No newline at end of file | ||
diff --git a/quantum/split_common/split_flags.h b/quantum/split_common/split_flags.h deleted file mode 100644 index aaac474a7..000000000 --- a/quantum/split_common/split_flags.h +++ /dev/null | |||
| @@ -1,15 +0,0 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <stdbool.h> | ||
| 4 | #include <stdint.h> | ||
| 5 | |||
| 6 | /** | ||
| 7 | * Global Flags | ||
| 8 | **/ | ||
| 9 | |||
| 10 | //RGB Stuff | ||
| 11 | extern volatile bool RGB_DIRTY; | ||
| 12 | |||
| 13 | |||
| 14 | //Backlight Stuff | ||
| 15 | extern volatile bool BACKLIT_DIRTY; | ||
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c index 5095cb8fd..da870f877 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | #include "keyboard.h" | 3 | #include "keyboard.h" |
| 4 | #include "config.h" | 4 | #include "config.h" |
| 5 | #include "timer.h" | 5 | #include "timer.h" |
| 6 | #include "split_flags.h" | ||
| 7 | #include "transport.h" | 6 | #include "transport.h" |
| 8 | #include "quantum.h" | 7 | #include "quantum.h" |
| 9 | 8 | ||
| @@ -60,10 +59,6 @@ static void keyboard_master_setup(void) { | |||
| 60 | #endif | 59 | #endif |
| 61 | #endif | 60 | #endif |
| 62 | transport_master_init(); | 61 | transport_master_init(); |
| 63 | |||
| 64 | // For master the Backlight info needs to be sent on startup | ||
| 65 | // Otherwise the salve won't start with the proper info until an update | ||
| 66 | BACKLIT_DIRTY = true; | ||
| 67 | } | 62 | } |
| 68 | 63 | ||
| 69 | static void keyboard_slave_setup(void) | 64 | static void keyboard_slave_setup(void) |
diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index 95738530e..b16852bc1 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c | |||
| @@ -3,146 +3,83 @@ | |||
| 3 | #include "matrix.h" | 3 | #include "matrix.h" |
| 4 | #include "quantum.h" | 4 | #include "quantum.h" |
| 5 | 5 | ||
| 6 | #define ROWS_PER_HAND (MATRIX_ROWS/2) | 6 | #define ROWS_PER_HAND (MATRIX_ROWS / 2) |
| 7 | 7 | ||
| 8 | #ifdef RGBLIGHT_ENABLE | 8 | #ifdef RGBLIGHT_ENABLE |
| 9 | # include "rgblight.h" | 9 | # include "rgblight.h" |
| 10 | #endif | 10 | #endif |
| 11 | 11 | ||
| 12 | #ifdef BACKLIGHT_ENABLE | 12 | #ifdef BACKLIGHT_ENABLE |
| 13 | # include "backlight.h" | 13 | # include "backlight.h" |
| 14 | extern backlight_config_t backlight_config; | 14 | extern backlight_config_t backlight_config; |
| 15 | #endif | 15 | #endif |
| 16 | 16 | ||
| 17 | #if defined(USE_I2C) || defined(EH) | 17 | #if defined(USE_I2C) || defined(EH) |
| 18 | 18 | ||
| 19 | #include "i2c.h" | 19 | # include "i2c_master.h" |
| 20 | # include "i2c_slave.h" | ||
| 20 | 21 | ||
| 21 | #ifndef SLAVE_I2C_ADDRESS | 22 | # define I2C_BACKLIT_START 0x00 |
| 22 | # define SLAVE_I2C_ADDRESS 0x32 | 23 | // Need 4 bytes for RGB (32 bit) |
| 23 | #endif | 24 | # define I2C_RGB_START 0x01 |
| 25 | # define I2C_KEYMAP_START 0x05 | ||
| 24 | 26 | ||
| 25 | #if (MATRIX_COLS > 8) | 27 | # define TIMEOUT 100 |
| 26 | # error "Currently only supports 8 COLS" | 28 | |
| 27 | #endif | 29 | # ifndef SLAVE_I2C_ADDRESS |
| 30 | # define SLAVE_I2C_ADDRESS 0x32 | ||
| 31 | # endif | ||
| 28 | 32 | ||
| 29 | // Get rows from other half over i2c | 33 | // Get rows from other half over i2c |
| 30 | bool transport_master(matrix_row_t matrix[]) { | 34 | bool transport_master(matrix_row_t matrix[]) { |
| 31 | int err = 0; | 35 | i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, ROWS_PER_HAND * sizeof(matrix_row_t), TIMEOUT); |
| 32 | 36 | ||
| 33 | // write backlight info | 37 | // write backlight info |
| 34 | #ifdef BACKLIGHT_ENABLE | 38 | # ifdef BACKLIGHT_ENABLE |
| 35 | if (BACKLIT_DIRTY) { | 39 | static uint8_t prev_level = ~0; |
| 36 | err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); | 40 | uint8_t level = get_backlight_level(); |
| 37 | if (err) { goto i2c_error; } | 41 | if (level != prev_level) { |
| 38 | 42 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIT_START, (void *)&level, sizeof(level), TIMEOUT); | |
| 39 | // Backlight location | 43 | prev_level = level; |
| 40 | err = i2c_master_write(I2C_BACKLIT_START); | ||
| 41 | if (err) { goto i2c_error; } | ||
| 42 | |||
| 43 | // Write backlight | ||
| 44 | i2c_master_write(get_backlight_level()); | ||
| 45 | |||
| 46 | BACKLIT_DIRTY = false; | ||
| 47 | } | ||
| 48 | #endif | ||
| 49 | |||
| 50 | err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); | ||
| 51 | if (err) { goto i2c_error; } | ||
| 52 | |||
| 53 | // start of matrix stored at I2C_KEYMAP_START | ||
| 54 | err = i2c_master_write(I2C_KEYMAP_START); | ||
| 55 | if (err) { goto i2c_error; } | ||
| 56 | |||
| 57 | // Start read | ||
| 58 | err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ); | ||
| 59 | if (err) { goto i2c_error; } | ||
| 60 | |||
| 61 | if (!err) { | ||
| 62 | int i; | ||
| 63 | for (i = 0; i < ROWS_PER_HAND-1; ++i) { | ||
| 64 | matrix[i] = i2c_master_read(I2C_ACK); | ||
| 65 | } | ||
| 66 | matrix[i] = i2c_master_read(I2C_NACK); | ||
| 67 | i2c_master_stop(); | ||
| 68 | } else { | ||
| 69 | i2c_error: // the cable is disconnceted, or something else went wrong | ||
| 70 | i2c_reset_state(); | ||
| 71 | return false; | ||
| 72 | } | 44 | } |
| 73 | 45 | # endif | |
| 74 | #ifdef RGBLIGHT_ENABLE | 46 | |
| 75 | if (RGB_DIRTY) { | 47 | # ifdef RGBLIGHT_ENABLE |
| 76 | err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); | 48 | static uint32_t prev_rgb = ~0; |
| 77 | if (err) { goto i2c_error; } | 49 | uint32_t rgb = eeconfig_read_rgblight(); |
| 78 | 50 | if (rgb != prev_rgb) { | |
| 79 | // RGB Location | 51 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgb, sizeof(rgb), TIMEOUT); |
| 80 | err = i2c_master_write(I2C_RGB_START); | 52 | prev_rgb = rgb; |
| 81 | if (err) { goto i2c_error; } | ||
| 82 | |||
| 83 | uint32_t dword = eeconfig_read_rgblight(); | ||
| 84 | |||
| 85 | // Write RGB | ||
| 86 | err = i2c_master_write_data(&dword, 4); | ||
| 87 | if (err) { goto i2c_error; } | ||
| 88 | |||
| 89 | RGB_DIRTY = false; | ||
| 90 | i2c_master_stop(); | ||
| 91 | } | 53 | } |
| 92 | #endif | 54 | # endif |
| 93 | 55 | ||
| 94 | return true; | 56 | return true; |
| 95 | } | 57 | } |
| 96 | 58 | ||
| 97 | void transport_slave(matrix_row_t matrix[]) { | 59 | void transport_slave(matrix_row_t matrix[]) { |
| 98 | 60 | for (int i = 0; i < ROWS_PER_HAND * sizeof(matrix_row_t); ++i) { | |
| 99 | for (int i = 0; i < ROWS_PER_HAND; ++i) | 61 | i2c_slave_reg[I2C_KEYMAP_START + i] = matrix[i]; |
| 100 | { | ||
| 101 | i2c_slave_buffer[I2C_KEYMAP_START + i] = matrix[i]; | ||
| 102 | } | ||
| 103 | // Read Backlight Info | ||
| 104 | #ifdef BACKLIGHT_ENABLE | ||
| 105 | if (BACKLIT_DIRTY) | ||
| 106 | { | ||
| 107 | backlight_set(i2c_slave_buffer[I2C_BACKLIT_START]); | ||
| 108 | BACKLIT_DIRTY = false; | ||
| 109 | } | 62 | } |
| 110 | #endif | ||
| 111 | #ifdef RGBLIGHT_ENABLE | ||
| 112 | if (RGB_DIRTY) | ||
| 113 | { | ||
| 114 | // Disable interupts (RGB data is big) | ||
| 115 | cli(); | ||
| 116 | // Create new DWORD for RGB data | ||
| 117 | uint32_t dword; | ||
| 118 | |||
| 119 | // Fill the new DWORD with the data that was sent over | ||
| 120 | uint8_t * dword_dat = (uint8_t *)(&dword); | ||
| 121 | for (int i = 0; i < 4; i++) | ||
| 122 | { | ||
| 123 | dword_dat[i] = i2c_slave_buffer[I2C_RGB_START + i]; | ||
| 124 | } | ||
| 125 | |||
| 126 | // Update the RGB now with the new data and set RGB_DIRTY to false | ||
| 127 | rgblight_update_dword(dword); | ||
| 128 | RGB_DIRTY = false; | ||
| 129 | // Re-enable interupts now that RGB is set | ||
| 130 | sei(); | ||
| 131 | } | ||
| 132 | #endif | ||
| 133 | } | ||
| 134 | 63 | ||
| 135 | void transport_master_init(void) { | 64 | // Read Backlight Info |
| 136 | i2c_master_init(); | 65 | # ifdef BACKLIGHT_ENABLE |
| 137 | } | 66 | backlight_set(i2c_slave_reg[I2C_BACKLIT_START]); |
| 67 | # endif | ||
| 138 | 68 | ||
| 139 | void transport_slave_init(void) { | 69 | # ifdef RGBLIGHT_ENABLE |
| 140 | i2c_slave_init(SLAVE_I2C_ADDRESS); | 70 | uint32_t rgb = *(uint32_t *)(i2c_slave_reg + I2C_RGB_START); |
| 71 | // Update the RGB with the new data | ||
| 72 | rgblight_update_dword(rgb); | ||
| 73 | # endif | ||
| 141 | } | 74 | } |
| 142 | 75 | ||
| 143 | #else // USE_SERIAL | 76 | void transport_master_init(void) { i2c_init(); } |
| 77 | |||
| 78 | void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); } | ||
| 144 | 79 | ||
| 145 | #include "serial.h" | 80 | #else // USE_SERIAL |
| 81 | |||
| 82 | # include "serial.h" | ||
| 146 | 83 | ||
| 147 | typedef struct _Serial_s2m_buffer_t { | 84 | typedef struct _Serial_s2m_buffer_t { |
| 148 | // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack | 85 | // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack |
| @@ -150,40 +87,40 @@ typedef struct _Serial_s2m_buffer_t { | |||
| 150 | } Serial_s2m_buffer_t; | 87 | } Serial_s2m_buffer_t; |
| 151 | 88 | ||
| 152 | typedef struct _Serial_m2s_buffer_t { | 89 | typedef struct _Serial_m2s_buffer_t { |
| 153 | #ifdef BACKLIGHT_ENABLE | 90 | # ifdef BACKLIGHT_ENABLE |
| 154 | uint8_t backlight_level; | 91 | uint8_t backlight_level; |
| 155 | #endif | 92 | # endif |
| 156 | #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | 93 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) |
| 157 | rgblight_config_t rgblight_config; //not yet use | 94 | rgblight_config_t rgblight_config; // not yet use |
| 158 | // | 95 | // |
| 159 | // When MCUs on both sides drive their respective RGB LED chains, | 96 | // When MCUs on both sides drive their respective RGB LED chains, |
| 160 | // it is necessary to synchronize, so it is necessary to communicate RGB information. | 97 | // it is necessary to synchronize, so it is necessary to communicate RGB |
| 161 | // In that case, define the RGBLIGHT_SPLIT macro. | 98 | // information. In that case, define the RGBLIGHT_SPLIT macro. |
| 162 | // | 99 | // |
| 163 | // Otherwise, if the master side MCU drives both sides RGB LED chains, | 100 | // Otherwise, if the master side MCU drives both sides RGB LED chains, |
| 164 | // there is no need to communicate. | 101 | // there is no need to communicate. |
| 165 | #endif | 102 | # endif |
| 166 | } Serial_m2s_buffer_t; | 103 | } Serial_m2s_buffer_t; |
| 167 | 104 | ||
| 168 | volatile Serial_s2m_buffer_t serial_s2m_buffer = {}; | 105 | volatile Serial_s2m_buffer_t serial_s2m_buffer = {}; |
| 169 | volatile Serial_m2s_buffer_t serial_m2s_buffer = {}; | 106 | volatile Serial_m2s_buffer_t serial_m2s_buffer = {}; |
| 170 | uint8_t volatile status0 = 0; | 107 | uint8_t volatile status0 = 0; |
| 171 | 108 | ||
| 172 | SSTD_t transactions[] = { | 109 | SSTD_t transactions[] = { |
| 173 | { (uint8_t *)&status0, | 110 | { |
| 174 | sizeof(serial_m2s_buffer), (uint8_t *)&serial_m2s_buffer, | 111 | (uint8_t *)&status0, |
| 175 | sizeof(serial_s2m_buffer), (uint8_t *)&serial_s2m_buffer | 112 | sizeof(serial_m2s_buffer), |
| 176 | } | 113 | (uint8_t *)&serial_m2s_buffer, |
| 114 | sizeof(serial_s2m_buffer), | ||
| 115 | (uint8_t *)&serial_s2m_buffer, | ||
| 116 | }, | ||
| 177 | }; | 117 | }; |
| 178 | 118 | ||
| 179 | void transport_master_init(void) | 119 | void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } |
| 180 | { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } | ||
| 181 | 120 | ||
| 182 | void transport_slave_init(void) | 121 | void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); } |
| 183 | { soft_serial_target_init(transactions, TID_LIMIT(transactions)); } | ||
| 184 | 122 | ||
| 185 | bool transport_master(matrix_row_t matrix[]) { | 123 | bool transport_master(matrix_row_t matrix[]) { |
| 186 | |||
| 187 | if (soft_serial_transaction()) { | 124 | if (soft_serial_transaction()) { |
| 188 | return false; | 125 | return false; |
| 189 | } | 126 | } |
| @@ -193,32 +130,29 @@ bool transport_master(matrix_row_t matrix[]) { | |||
| 193 | matrix[i] = serial_s2m_buffer.smatrix[i]; | 130 | matrix[i] = serial_s2m_buffer.smatrix[i]; |
| 194 | } | 131 | } |
| 195 | 132 | ||
| 196 | #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | 133 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) |
| 197 | // Code to send RGB over serial goes here (not implemented yet) | 134 | // Code to send RGB over serial goes here (not implemented yet) |
| 198 | #endif | 135 | # endif |
| 199 | 136 | ||
| 200 | #ifdef BACKLIGHT_ENABLE | 137 | # ifdef BACKLIGHT_ENABLE |
| 201 | // Write backlight level for slave to read | 138 | // Write backlight level for slave to read |
| 202 | serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0; | 139 | serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0; |
| 203 | #endif | 140 | # endif |
| 204 | 141 | ||
| 205 | return true; | 142 | return true; |
| 206 | } | 143 | } |
| 207 | 144 | ||
| 208 | void transport_slave(matrix_row_t matrix[]) { | 145 | void transport_slave(matrix_row_t matrix[]) { |
| 209 | |||
| 210 | // TODO: if MATRIX_COLS > 8 change to pack() | 146 | // TODO: if MATRIX_COLS > 8 change to pack() |
| 211 | for (int i = 0; i < ROWS_PER_HAND; ++i) | 147 | for (int i = 0; i < ROWS_PER_HAND; ++i) { |
| 212 | { | ||
| 213 | serial_s2m_buffer.smatrix[i] = matrix[i]; | 148 | serial_s2m_buffer.smatrix[i] = matrix[i]; |
| 214 | } | 149 | } |
| 215 | #ifdef BACKLIGHT_ENABLE | 150 | # ifdef BACKLIGHT_ENABLE |
| 216 | backlight_set(serial_m2s_buffer.backlight_level); | 151 | backlight_set(serial_m2s_buffer.backlight_level); |
| 217 | #endif | 152 | # endif |
| 218 | #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | 153 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) |
| 219 | // Add serial implementation for RGB here | 154 | // Add serial implementation for RGB here |
| 220 | #endif | 155 | # endif |
| 221 | |||
| 222 | } | 156 | } |
| 223 | 157 | ||
| 224 | #endif | 158 | #endif |
