From cc313d6d57ab3a94495cd0d6beea7c2ee2a894ce Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 22 Sep 2021 14:18:39 -0700 Subject: [PATCH] Check in non-working renamed plugin with the first little bit of work on porting --- ...leidoscope-Hardware-Keyboardio-Model100.h} | 6 +- .../keyboardio/{Model01.cpp => Model100.cpp} | 137 ++--- .../keyboardio/{Model01.h => Model100.h} | 42 +- .../src/kaleidoscope/device/keyboardio/twi.c | 574 ------------------ .../src/kaleidoscope/device/keyboardio/twi.h | 57 -- .../{Model01Side.cpp => Model100Side.cpp} | 34 +- .../{Model01Side.h => Model100Side.h} | 12 +- 7 files changed, 113 insertions(+), 749 deletions(-) rename plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/{Kaleidoscope-Hardware-Keyboardio-Model01.h => Kaleidoscope-Hardware-Keyboardio-Model100.h} (75%) rename plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/{Model01.cpp => Model100.cpp} (56%) rename plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/{Model01.h => Model100.h} (82%) delete mode 100644 plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/twi.c delete mode 100644 plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/twi.h rename plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/{Model01Side.cpp => Model100Side.cpp} (88%) rename plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/{Model01Side.h => Model100Side.h} (93%) diff --git a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/Kaleidoscope-Hardware-Keyboardio-Model01.h b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/Kaleidoscope-Hardware-Keyboardio-Model100.h similarity index 75% rename from plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/Kaleidoscope-Hardware-Keyboardio-Model01.h rename to plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/Kaleidoscope-Hardware-Keyboardio-Model100.h index a83fd173..234f4337 100644 --- a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/Kaleidoscope-Hardware-Keyboardio-Model01.h +++ b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/Kaleidoscope-Hardware-Keyboardio-Model100.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- - * Kaleidoscope-Hardware-Keyboardio-Model01 -- Keyboardio Model01 hardware support for Kaleidoscope - * Copyright (C) 2017-2019 Keyboard.io, Inc + * Kaleidoscope-Hardware-Keyboardio-Model100 -- Keyboardio Model100 hardware support for Kaleidoscope + * Copyright (C) 2021 Keyboard.io, Inc * * 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 @@ -17,4 +17,4 @@ #pragma once -#include "kaleidoscope/device/keyboardio/Model01.h" +#include "kaleidoscope/device/keyboardio/Model100.h" diff --git a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model01.cpp b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model100.cpp similarity index 56% rename from plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model01.cpp rename to plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model100.cpp index 61681091..ee0b27da 100644 --- a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model01.cpp +++ b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model100.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- - * Kaleidoscope-Hardware-Model01 -- Keyboard.io Model01 hardware support for Kaleidoscope - * Copyright (C) 2017-2020 Keyboard.io, Inc + * Kaleidoscope-Hardware-Model100 -- Keyboardio Model 100 hardware support for Kaleidoscope + * Copyright (C) 2021 Keyboard.io, Inc * * 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 @@ -15,10 +15,10 @@ * this program. If not, see . */ -#ifdef ARDUINO_AVR_MODEL01 +#ifdef ARDUINO_GD32_keyboardio_model_100 #include "Arduino.h" // for PROGMEM -#include "kaleidoscope/device/keyboardio/Model01.h" // for Model01LEDDriver... +#include "kaleidoscope/device/keyboardio/Model100.h" // for Model100LEDDriver... #include "kaleidoscope/key_events.h" #include "kaleidoscope/driver/keyscanner/Base_Impl.h" @@ -31,23 +31,23 @@ namespace kaleidoscope { namespace device { namespace keyboardio { -constexpr uint8_t Model01LEDDriverProps::key_led_map[] PROGMEM; +constexpr uint8_t Model100LEDDriverProps::key_led_map[] PROGMEM; #ifndef KALEIDOSCOPE_VIRTUAL_BUILD -/********* Model01Hands *********/ +/********* Model100Hands *********/ -struct Model01Hands { - static driver::keyboardio::Model01Side leftHand; - static driver::keyboardio::Model01Side rightHand; +struct Model100Hands { + static driver::keyboardio::Model100Side leftHand; + static driver::keyboardio::Model100Side rightHand; static void setup(); }; -driver::keyboardio::Model01Side Model01Hands::leftHand(0); -driver::keyboardio::Model01Side Model01Hands::rightHand(3); +driver::keyboardio::Model100Side Model100Hands::leftHand(0); +driver::keyboardio::Model100Side Model100Hands::rightHand(3); -void Model01Hands::setup(void) { +void Model100Hands::setup(void) { // This lets the keyboard pull up to 1.6 amps from the host. // That violates the USB spec. But it sure is pretty looking DDRE |= _BV(6); @@ -59,29 +59,29 @@ void Model01Hands::setup(void) { } /********* LED Driver *********/ -bool Model01LEDDriver::isLEDChanged = true; +bool Model100LEDDriver::isLEDChanged = true; -void Model01LEDDriver::setBrightness(uint8_t brightness) { - Model01Hands::leftHand.setBrightness(brightness); - Model01Hands::rightHand.setBrightness(brightness); +void Model100LEDDriver::setBrightness(uint8_t brightness) { + Model100Hands::leftHand.setBrightness(brightness); + Model100Hands::rightHand.setBrightness(brightness); isLEDChanged = true; } -uint8_t Model01LEDDriver::getBrightness() { - return Model01Hands::leftHand.getBrightness(); +uint8_t Model100LEDDriver::getBrightness() { + return Model100Hands::leftHand.getBrightness(); } -void Model01LEDDriver::setCrgbAt(uint8_t i, cRGB crgb) { +void Model100LEDDriver::setCrgbAt(uint8_t i, cRGB crgb) { if (i < 32) { cRGB oldColor = getCrgbAt(i); isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); - Model01Hands::leftHand.ledData.leds[i] = crgb; + Model100Hands::leftHand.ledData.leds[i] = crgb; } else if (i < 64) { cRGB oldColor = getCrgbAt(i); isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); - Model01Hands::rightHand.ledData.leds[i - 32] = crgb; + Model100Hands::rightHand.ledData.leds[i - 32] = crgb; } else { // TODO(anyone): // how do we want to handle debugging assertions about crazy user @@ -89,18 +89,18 @@ void Model01LEDDriver::setCrgbAt(uint8_t i, cRGB crgb) { } } -cRGB Model01LEDDriver::getCrgbAt(uint8_t i) { +cRGB Model100LEDDriver::getCrgbAt(uint8_t i) { if (i >= 64) return {0, 0, 0}; if (i < 32) { - return Model01Hands::leftHand.ledData.leds[i]; + return Model100Hands::leftHand.ledData.leds[i]; } else { - return Model01Hands::rightHand.ledData.leds[i - 32]; + return Model100Hands::rightHand.ledData.leds[i - 32]; } } -void Model01LEDDriver::syncLeds() { +void Model100LEDDriver::syncLeds() { if (!isLEDChanged) return; @@ -110,63 +110,60 @@ void Model01LEDDriver::syncLeds() { // we run into a race condition with updating the next bank // on an ATTiny before it's done writing the previous one to memory - Model01Hands::leftHand.sendLEDData(); - Model01Hands::rightHand.sendLEDData(); + Model100Hands::leftHand.sendLEDData(); + Model100Hands::rightHand.sendLEDData(); - Model01Hands::leftHand.sendLEDData(); - Model01Hands::rightHand.sendLEDData(); + Model100Hands::leftHand.sendLEDData(); + Model100Hands::rightHand.sendLEDData(); - Model01Hands::leftHand.sendLEDData(); - Model01Hands::rightHand.sendLEDData(); + Model100Hands::leftHand.sendLEDData(); + Model100Hands::rightHand.sendLEDData(); - Model01Hands::leftHand.sendLEDData(); - Model01Hands::rightHand.sendLEDData(); + Model100Hands::leftHand.sendLEDData(); + Model100Hands::rightHand.sendLEDData(); isLEDChanged = false; } -boolean Model01LEDDriver::ledPowerFault() { - if (PINB & _BV(4)) { - return true; - } else { - return false; - } +boolean Model100LEDDriver::ledPowerFault() { + // TODO remove - obsolete } /********* Key scanner *********/ -driver::keyboardio::keydata_t Model01KeyScanner::leftHandState; -driver::keyboardio::keydata_t Model01KeyScanner::rightHandState; -driver::keyboardio::keydata_t Model01KeyScanner::previousLeftHandState; -driver::keyboardio::keydata_t Model01KeyScanner::previousRightHandState; +driver::keyboardio::keydata_t Model100KeyScanner::leftHandState; +driver::keyboardio::keydata_t Model100KeyScanner::rightHandState; +driver::keyboardio::keydata_t Model100KeyScanner::previousLeftHandState; +driver::keyboardio::keydata_t Model100KeyScanner::previousRightHandState; -void Model01KeyScanner::enableScannerPower(void) { - // Turn on power to the LED net - DDRC |= _BV(7); - PORTC |= _BV(7); +void Model100KeyScanner::enableScannerPower(void) { + // Turn on power to the 5V net + // + pinMode(PC13, OUTPUT_OPEN_DRAIN); + digitalWrite(PC13, LOW); } -void Model01KeyScanner::setup() { +void Model100KeyScanner::setup() { wdt_disable(); delay(100); enableScannerPower(); } -void Model01KeyScanner::readMatrix() { +void Model100KeyScanner::readMatrix() { //scan the Keyboard matrix looking for connections previousLeftHandState = leftHandState; previousRightHandState = rightHandState; - if (Model01Hands::leftHand.readKeys()) { - leftHandState = Model01Hands::leftHand.getKeyData(); + if (Model100Hands::leftHand.readKeys()) { + leftHandState = Model100Hands::leftHand.getKeyData(); } - if (Model01Hands::rightHand.readKeys()) { - rightHandState = Model01Hands::rightHand.getKeyData(); + if (Model100Hands::rightHand.readKeys()) { + rightHandState = Model100Hands::rightHand.getKeyData(); } } -void Model01KeyScanner::actOnHalfRow(byte row, byte colState, byte colPrevState, byte startPos) { +void Model100KeyScanner::actOnHalfRow(byte row, byte colState, byte colPrevState, byte startPos) { if ((colState != colPrevState) || (colState != 0)) { for (byte col = 0; col < 8; col++) { // Build up the key state for row, col @@ -182,7 +179,7 @@ void Model01KeyScanner::actOnHalfRow(byte row, byte colState, byte colPrevState, } } -void Model01KeyScanner::actOnMatrixScan() { +void Model100KeyScanner::actOnMatrixScan() { for (byte row = 0; row < 4; row++) { actOnHalfRow(row, leftHandState.rows[row], previousLeftHandState.rows[row], 7); actOnHalfRow(row, rightHandState.rows[row], previousRightHandState.rows[row], 15); @@ -190,17 +187,17 @@ void Model01KeyScanner::actOnMatrixScan() { } -void Model01KeyScanner::scanMatrix() { +void Model100KeyScanner::scanMatrix() { readMatrix(); actOnMatrixScan(); } -void Model01KeyScanner::setKeyscanInterval(uint8_t interval) { - Model01Hands::leftHand.setKeyscanInterval(interval); - Model01Hands::rightHand.setKeyscanInterval(interval); +void Model100KeyScanner::setKeyscanInterval(uint8_t interval) { + Model100Hands::leftHand.setKeyscanInterval(interval); + Model100Hands::rightHand.setKeyscanInterval(interval); } -bool Model01KeyScanner::isKeyswitchPressed(KeyAddr key_addr) { +bool Model100KeyScanner::isKeyswitchPressed(KeyAddr key_addr) { auto row = key_addr.row(); auto col = key_addr.col(); if (col <= 7) { @@ -210,7 +207,7 @@ bool Model01KeyScanner::isKeyswitchPressed(KeyAddr key_addr) { } } -bool Model01KeyScanner::wasKeyswitchPressed(KeyAddr key_addr) { +bool Model100KeyScanner::wasKeyswitchPressed(KeyAddr key_addr) { auto row = key_addr.row(); auto col = key_addr.col(); if (col <= 7) { @@ -220,27 +217,25 @@ bool Model01KeyScanner::wasKeyswitchPressed(KeyAddr key_addr) { } } -uint8_t Model01KeyScanner::pressedKeyswitchCount() { +uint8_t Model100KeyScanner::pressedKeyswitchCount() { return __builtin_popcountl(leftHandState.all) + __builtin_popcountl(rightHandState.all); } -uint8_t Model01KeyScanner::previousPressedKeyswitchCount() { +uint8_t Model100KeyScanner::previousPressedKeyswitchCount() { return __builtin_popcountl(previousLeftHandState.all) + __builtin_popcountl(previousRightHandState.all); } /********* Hardware plugin *********/ -void Model01::setup() { - Model01Hands::setup(); - kaleidoscope::device::Base::setup(); - - TWBR = 12; // This is 400mhz, which is the fastest we can drive the ATTiny +void Model100::setup() { + Model100Hands::setup(); + kaleidoscope::device::Base::setup(); } -void Model01::enableHardwareTestMode() { +void Model100::enableHardwareTestMode() { // Toggle the programming LEDS on - PORTD |= (1 << 5); - PORTB |= (1 << 0); + // TODO PORTD |= (1 << 5); + // TOOD PORTB |= (1 << 0); // Disable the debouncer on the ATTinys KeyScanner::setKeyscanInterval(2); diff --git a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model01.h b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model100.h similarity index 82% rename from plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model01.h rename to plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model100.h index 14f60631..606f3e93 100644 --- a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model01.h +++ b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model100.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- - * Kaleidoscope-Hardware-Model01 -- Keyboard.io Model01 hardware support for Kaleidoscope - * Copyright (C) 2017-2020 Keyboard.io, Inc + * Kaleidoscope-Hardware-Model100 -- Keyboardio Model100 hardware support for Kaleidoscope + * Copyright (C) 2017-2021 Keyboard.io, Inc * * 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 @@ -17,7 +17,7 @@ #pragma once -#ifdef ARDUINO_AVR_MODEL01 +#ifdef ARDUINO_GD32_keyboardio_model_100 #include @@ -32,15 +32,15 @@ struct cRGB { #include "kaleidoscope/device/ATmega32U4Keyboard.h" #include "kaleidoscope/driver/keyscanner/Base.h" -#include "kaleidoscope/driver/keyboardio/Model01Side.h" +#include "kaleidoscope/driver/keyboardio/Model100Side.h" #include "kaleidoscope/driver/led/Base.h" -#include "kaleidoscope/driver/bootloader/avr/Caterina.h" +#include "kaleidoscope/driver/bootloader/gd32/Base.h" namespace kaleidoscope { namespace device { namespace keyboardio { -struct Model01LEDDriverProps : public kaleidoscope::driver::led::BaseProps { +struct Model100LEDDriverProps : public kaleidoscope::driver::led::BaseProps { static constexpr uint8_t led_count = 64; static constexpr uint8_t key_led_map[] PROGMEM = { 3, 4, 11, 12, 19, 20, 26, 27, 36, 37, 43, 44, 51, 52, 59, 60, @@ -51,7 +51,7 @@ struct Model01LEDDriverProps : public kaleidoscope::driver::led::BaseProps { }; #ifndef KALEIDOSCOPE_VIRTUAL_BUILD -class Model01LEDDriver : public kaleidoscope::driver::led::Base { +class Model100LEDDriver : public kaleidoscope::driver::led::Base { public: static void syncLeds(); static void setCrgbAt(uint8_t i, cRGB crgb); @@ -66,19 +66,19 @@ class Model01LEDDriver : public kaleidoscope::driver::led::Base KeyAddr; }; #ifndef KALEIDOSCOPE_VIRTUAL_BUILD -class Model01KeyScanner : public kaleidoscope::driver::keyscanner::Base { +class Model100KeyScanner : public kaleidoscope::driver::keyscanner::Base { private: - typedef Model01KeyScanner ThisType; + typedef Model100KeyScanner ThisType; public: static void setup(); static void scanMatrix(); @@ -103,21 +103,21 @@ class Model01KeyScanner : public kaleidoscope::driver::keyscanner::Base { +class Model100 : public kaleidoscope::device::Base { public: void setup(); @@ -129,7 +129,7 @@ class Model01 : public kaleidoscope::device::ATmega32U4Keyboard { } // namespace keyboardio } // namespace device -EXPORT_DEVICE(kaleidoscope::device::keyboardio::Model01) +EXPORT_DEVICE(kaleidoscope::device::keyboardio::Model100) } diff --git a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/twi.c b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/twi.c deleted file mode 100644 index bd00c078..00000000 --- a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/twi.c +++ /dev/null @@ -1,574 +0,0 @@ -/* - twi.c - TWI/I2C library for Wiring & Arduino - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - This library is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) any - later version. - - This library 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 Lesser General Public License for more - details. - - You should have received a copy of the GNU Lesser General Public License along - with this program. If not, see . - - Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts -*/ - -#if defined(__AVR__) && !defined(KALEIDOSCOPE_VIRTUAL_BUILD) - -#define ENABLE_TWI_SLAVE_MODE 0 - -#include -#include -#include -#include -#include -#include -// #include "Arduino.h" // for digitalWrite - -#define true 1 -#define false 0 - - -#ifndef cbi -#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) -#endif - -#ifndef sbi -#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) -#endif - -#include "pins_arduino.h" -#include "twi.h" - -static volatile uint8_t twi_state; -static volatile uint8_t twi_slarw; -static volatile uint8_t twi_sendStop; // should the transaction end with a stop -static volatile uint8_t twi_inRepStart; // in the middle of a repeated start - -static void (*twi_onSlaveTransmit)(void); -static void (*twi_onSlaveReceive)(uint8_t*, int); - -static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_masterBufferIndex; -static volatile uint8_t twi_masterBufferLength; - -static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_txBufferIndex; -static volatile uint8_t twi_txBufferLength; - -#if ENABLE_TWI_SLAVE_MODE -static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_rxBufferIndex; -#endif - -static volatile uint8_t twi_error; - -/* - * Function twi_init - * Desc readys twi pins and sets twi bitrate - * Input none - * Output none - */ -void twi_init(void) { - // initialize state - twi_state = TWI_READY; - twi_sendStop = true; // default value - twi_inRepStart = false; - - // activate internal pullups for twi. - // digitalWrite(SDA, 1); - PORTD |= _BV(0); - // digitalWrite(SCL, 1); - PORTD |= _BV(1); - - // initialize twi prescaler and bit rate - cbi(TWSR, TWPS0); - cbi(TWSR, TWPS1); - TWBR = ((F_CPU / TWI_FREQ) - 16) / 2; - - /* twi bit rate formula from atmega128 manual pg 204 - SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) - note: TWBR should be 10 or higher for master mode - It is 72 for a 16mhz Wiring board with 100kHz TWI */ - - // enable twi module, acks, and twi interrupt - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); -} - -/* - * Function twi_disable - * Desc disables twi pins - * Input none - * Output none - */ -void twi_disable(void) { - // disable twi module, acks, and twi interrupt - TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA)); - - // deactivate internal pullups for twi. - // digitalWrite(SDA, 0); - PORTD &= ~_BV(0); - // digitalWrite(SCL, 0); - PORTD &= ~_BV(1); -} - -/* - * Function twi_slaveInit - * Desc sets slave address and enables interrupt - * Input none - * Output none - */ -void twi_setAddress(uint8_t address) { - // set twi slave address (skip over TWGCE bit) - TWAR = address << 1; -} - -/* - * Function twi_setClock - * Desc sets twi bit rate - * Input Clock Frequency - * Output none - */ -void twi_setFrequency(uint32_t frequency) { - TWBR = ((F_CPU / frequency) - 16) / 2; - - /* twi bit rate formula from atmega128 manual pg 204 - SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) - note: TWBR should be 10 or higher for master mode - It is 72 for a 16mhz Wiring board with 100kHz TWI */ -} - -/* - * Function twi_readFrom - * Desc attempts to become twi bus master and read a - * series of bytes from a device on the bus - * Input address: 7bit i2c device address - * data: pointer to byte array - * length: number of bytes to read into array - * sendStop: Boolean indicating whether to send a stop at the end - * Output number of bytes read - */ -uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) { - uint8_t i; - - // ensure data will fit into buffer - if (TWI_BUFFER_LENGTH < length) { - return 0; - } - - // wait until twi is ready, become master receiver - while (TWI_READY != twi_state) { - continue; - } - twi_state = TWI_MRX; - twi_sendStop = sendStop; - // reset error state (0xFF.. no error occured) - twi_error = 0xFF; - - // initialize buffer iteration vars - twi_masterBufferIndex = 0; - twi_masterBufferLength = length - 1; // This is not intuitive, read on... - // On receive, the previously configured ACK/NACK setting is transmitted in - // response to the received byte before the interrupt is signalled. - // Therefor we must actually set NACK when the _next_ to last byte is - // received, causing that NACK to be sent in response to receiving the last - // expected byte of data. - - // build sla+w, slave device address + w bit - twi_slarw = TW_READ; - twi_slarw |= address << 1; - - if (true == twi_inRepStart) { - // if we're in the repeated start state, then we've already sent the start, - // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. - // We need to remove ourselves from the repeated start state before we enable interrupts, - // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning - // up. Also, don't enable the START interrupt. There may be one pending from the - // repeated start that we sent ourselves, and that would really confuse things. - twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR - do { - TWDR = twi_slarw; - } while (TWCR & _BV(TWWC)); - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START - } else - // send start condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); - - // wait for read operation to complete - while (TWI_MRX == twi_state) { - continue; - } - - if (twi_masterBufferIndex < length) - length = twi_masterBufferIndex; - - // copy twi buffer to data - for (i = 0; i < length; ++i) { - data[i] = twi_masterBuffer[i]; - } - - return length; -} - -/* - * Function twi_writeTo - * Desc attempts to become twi bus master and write a - * series of bytes to a device on the bus - * Input address: 7bit i2c device address - * data: pointer to byte array - * length: number of bytes in array - * wait: boolean indicating to wait for write or not - * sendStop: boolean indicating whether or not to send a stop at the end - * Output 0 .. success - * 1 .. length to long for buffer - * 2 .. address send, NACK received - * 3 .. data send, NACK received - * 4 .. other twi error (lost bus arbitration, bus error, ..) - */ -uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) { - uint8_t i; - - // ensure data will fit into buffer - if (TWI_BUFFER_LENGTH < length) { - return 1; - } - - // wait until twi is ready, become master transmitter - while (TWI_READY != twi_state) { - continue; - } - twi_state = TWI_MTX; - twi_sendStop = sendStop; - // reset error state (0xFF.. no error occured) - twi_error = 0xFF; - - // initialize buffer iteration vars - twi_masterBufferIndex = 0; - twi_masterBufferLength = length; - - // copy data to twi buffer - for (i = 0; i < length; ++i) { - twi_masterBuffer[i] = data[i]; - } - - // build sla+w, slave device address + w bit - twi_slarw = TW_WRITE; - twi_slarw |= address << 1; - - // if we're in a repeated start, then we've already sent the START - // in the ISR. Don't do it again. - // - if (true == twi_inRepStart) { - // if we're in the repeated start state, then we've already sent the start, - // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. - // We need to remove ourselves from the repeated start state before we enable interrupts, - // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning - // up. Also, don't enable the START interrupt. There may be one pending from the - // repeated start that we sent outselves, and that would really confuse things. - twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR - do { - TWDR = twi_slarw; - } while (TWCR & _BV(TWWC)); - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START - } else - // send start condition - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs - - // wait for write operation to complete - while (wait && (TWI_MTX == twi_state)) { - continue; - } - - switch (twi_error) { - case 0xFF: - return 0; // success - case TW_MT_SLA_NACK: - return 2; // error: address send, nack received - case TW_MT_DATA_NACK: - return 3; // error: data send, nack received - default: - return 4; // other twi error - } -} - -/* - * Function twi_transmit - * Desc fills slave tx buffer with data - * must be called in slave tx event callback - * Input data: pointer to byte array - * length: number of bytes in array - * Output 1 length too long for buffer - * 2 not slave transmitter - * 0 ok - */ -uint8_t twi_transmit(const uint8_t* data, uint8_t length) { - uint8_t i; - - // ensure data will fit into buffer - if (TWI_BUFFER_LENGTH < (twi_txBufferLength + length)) { - return 1; - } - - // ensure we are currently a slave transmitter - if (TWI_STX != twi_state) { - return 2; - } - - // set length and copy data into tx buffer - for (i = 0; i < length; ++i) { - twi_txBuffer[twi_txBufferLength + i] = data[i]; - } - twi_txBufferLength += length; - - return 0; -} - -/* - * Function twi_attachSlaveRxEvent - * Desc sets function called before a slave read operation - * Input function: callback function to use - * Output none - */ -void twi_attachSlaveRxEvent(void (*function)(uint8_t*, int)) { - twi_onSlaveReceive = function; -} - -/* - * Function twi_attachSlaveTxEvent - * Desc sets function called before a slave write operation - * Input function: callback function to use - * Output none - */ -void twi_attachSlaveTxEvent(void (*function)(void)) { - twi_onSlaveTransmit = function; -} - -/* - * Function twi_reply - * Desc sends byte or readys receive line - * Input ack: byte indicating to ack or to nack - * Output none - */ -void twi_reply(uint8_t ack) { - // transmit master read ready signal, with or without ack - if (ack) { - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); - } else { - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); - } -} - -/* - * Function twi_stop - * Desc relinquishes bus master status - * Input none - * Output none - */ -void twi_stop(void) { - // send stop condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); - - // wait for stop condition to be exectued on bus - // TWINT is not set after a stop condition! - while (TWCR & _BV(TWSTO)) { - continue; - } - - // update twi state - twi_state = TWI_READY; -} - -/* - * Function twi_releaseBus - * Desc releases bus control - * Input none - * Output none - */ -void twi_releaseBus(void) { - // release bus - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); - - // update twi state - twi_state = TWI_READY; -} - -ISR(TWI_vect) { - switch (TW_STATUS) { - // All Master - case TW_START: // sent start condition - /* Falls through. */ - case TW_REP_START: // sent repeated start condition - // copy device address and r/w bit to output register and ack - TWDR = twi_slarw; - twi_reply(1); - break; - - // Master Transmitter - case TW_MT_SLA_ACK: // slave receiver acked address - /* Falls through. */ - case TW_MT_DATA_ACK: // slave receiver acked data - // if there is data to send, send it, otherwise stop - if (twi_masterBufferIndex < twi_masterBufferLength) { - // copy data to output register and ack - TWDR = twi_masterBuffer[twi_masterBufferIndex++]; - twi_reply(1); - } else { - if (twi_sendStop) - twi_stop(); - else { - twi_inRepStart = true; // we're gonna send the START - // don't enable the interrupt. We'll generate the start, but we - // avoid handling the interrupt until we're in the next transaction, - // at the point where we would normally issue the start. - TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN) ; - twi_state = TWI_READY; - } - } - break; - case TW_MT_SLA_NACK: // address sent, nack received - twi_error = TW_MT_SLA_NACK; - twi_stop(); - break; - case TW_MT_DATA_NACK: // data sent, nack received - twi_error = TW_MT_DATA_NACK; - twi_stop(); - break; - case TW_MT_ARB_LOST: // lost bus arbitration - twi_error = TW_MT_ARB_LOST; - twi_releaseBus(); - break; - - // Master Receiver - case TW_MR_DATA_ACK: // data received, ack sent - // put byte into buffer - twi_masterBuffer[twi_masterBufferIndex++] = TWDR; - /* intentionally fall through */ - case TW_MR_SLA_ACK: // address sent, ack received - // ack if more bytes are expected, otherwise nack - if (twi_masterBufferIndex < twi_masterBufferLength) { - twi_reply(1); - } else { - twi_reply(0); - } - break; - case TW_MR_DATA_NACK: // data received, nack sent - // put final byte into buffer - twi_masterBuffer[twi_masterBufferIndex++] = TWDR; - if (twi_sendStop) - twi_stop(); - else { - twi_inRepStart = true; // we're gonna send the START - // don't enable the interrupt. We'll generate the start, but we - // avoid handling the interrupt until we're in the next transaction, - // at the point where we would normally issue the start. - TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN) ; - twi_state = TWI_READY; - } - break; - case TW_MR_SLA_NACK: // address sent, nack received - twi_stop(); - break; - // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case - -#if ENABLE_TWI_SLAVE_MODE - // Slave Receiver - case TW_SR_SLA_ACK: // addressed, returned ack - /* Falls through. */ - case TW_SR_GCALL_ACK: // addressed generally, returned ack - /* Falls through. */ - case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack - /* Falls through. */ - case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack - // enter slave receiver mode - twi_state = TWI_SRX; - // indicate that rx buffer can be overwritten and ack - twi_rxBufferIndex = 0; - twi_reply(1); - break; - case TW_SR_DATA_ACK: // data received, returned ack - /* Falls through. */ - case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack - // if there is still room in the rx buffer - if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) { - // put byte in buffer and ack - twi_rxBuffer[twi_rxBufferIndex++] = TWDR; - twi_reply(1); - } else { - // otherwise nack - twi_reply(0); - } - break; - case TW_SR_STOP: // stop or repeated start condition received - // ack future responses and leave slave receiver state - twi_releaseBus(); - // put a null char after data if there's room - if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) { - twi_rxBuffer[twi_rxBufferIndex] = '\0'; - } - // callback to user defined callback - twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); - // since we submit rx buffer to "wire" library, we can reset it - twi_rxBufferIndex = 0; - break; - case TW_SR_DATA_NACK: // data received, returned nack - /* Falls through. */ - case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack - // nack back at master - twi_reply(0); - break; - - // Slave Transmitter - case TW_ST_SLA_ACK: // addressed, returned ack - /* Falls through. */ - case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack - // enter slave transmitter mode - twi_state = TWI_STX; - // ready the tx buffer index for iteration - twi_txBufferIndex = 0; - // set tx buffer length to be zero, to verify if user changes it - twi_txBufferLength = 0; - // request for txBuffer to be filled and length to be set - // note: user must call twi_transmit(bytes, length) to do this - twi_onSlaveTransmit(); - // if they didn't change buffer & length, initialize it - if (0 == twi_txBufferLength) { - twi_txBufferLength = 1; - twi_txBuffer[0] = 0x00; - } - // transmit first byte from buffer, fall through - case TW_ST_DATA_ACK: // byte sent, ack returned - // copy data to output register - TWDR = twi_txBuffer[twi_txBufferIndex++]; - // if there is more to send, ack, otherwise nack - if (twi_txBufferIndex < twi_txBufferLength) { - twi_reply(1); - } else { - twi_reply(0); - } - break; - case TW_ST_DATA_NACK: // received nack, we are done - /* Falls through. */ - case TW_ST_LAST_DATA: // received ack, but we are done already! - // ack future responses - twi_reply(1); - // leave slave receiver state - twi_state = TWI_READY; - break; -#endif - - // All - case TW_NO_INFO: // no state information - break; - case TW_BUS_ERROR: // bus error, illegal stop/start - twi_error = TW_BUS_ERROR; - twi_stop(); - break; - } -} - -#endif diff --git a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/twi.h b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/twi.h deleted file mode 100644 index 773ce9cb..00000000 --- a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/twi.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - twi.h - TWI/I2C library for Wiring & Arduino - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - This library is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) any - later version. - - This library 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 Lesser General Public License for more - details. - - You should have received a copy of the GNU Lesser General Public License along - with this program. If not, see . -*/ - -#pragma once - -#ifdef __AVR__ - -#ifndef KALEIDOSCOPE_VIRTUAL_BUILD - -#include - -//#define ATMEGA8 - -#ifndef TWI_FREQ -#define TWI_FREQ 100000L -#endif - -#ifndef TWI_BUFFER_LENGTH -#define TWI_BUFFER_LENGTH 192 -#endif - -#define TWI_READY 0 -#define TWI_MRX 1 -#define TWI_MTX 2 -#define TWI_SRX 3 -#define TWI_STX 4 - -void twi_init(void); -void twi_disable(void); -void twi_setAddress(uint8_t); -void twi_setFrequency(uint32_t); -uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t); -uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); -uint8_t twi_transmit(const uint8_t*, uint8_t); -void twi_attachSlaveRxEvent(void (*)(uint8_t*, int)); -void twi_attachSlaveTxEvent(void (*)(void)); -void twi_reply(uint8_t); -void twi_stop(void); -void twi_releaseBus(void); - -#endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD -#endif diff --git a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model01Side.cpp b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model100Side.cpp similarity index 88% rename from plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model01Side.cpp rename to plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model100Side.cpp index 374d1986..8d4c6e31 100644 --- a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model01Side.cpp +++ b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model100Side.cpp @@ -1,5 +1,5 @@ -/* kaleidoscope::driver::keyboardio::Model01Side - * Copyright (C) 2015-2020 Keyboard.io, Inc +/* kaleidoscope::driver::keyboardio::Model100Side + * Copyright (C) 2021 Keyboard.io, Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,7 @@ #ifndef KALEIDOSCOPE_VIRTUAL_BUILD #include -#include "Model01Side.h" +#include "Model100Side.h" extern "C" { #include "kaleidoscope/device/keyboardio/twi.h" @@ -40,7 +40,7 @@ namespace keyboardio { uint8_t twi_uninitialized = 1; -Model01Side::Model01Side(byte setAd01) { +Model100Side::Model100Side(byte setAd01) { ad01 = setAd01; addr = SCANNER_I2C_ADDR_BASE | ad01; if (twi_uninitialized--) { @@ -49,7 +49,7 @@ Model01Side::Model01Side(byte setAd01) { } // Returns the relative controller addresss. The expected range is 0-3 -uint8_t Model01Side::controllerAddress() { +uint8_t Model100Side::controllerAddress() { return ad01; } @@ -70,7 +70,7 @@ uint8_t Model01Side::controllerAddress() { // // returns the Wire.endTransmission code (0 = success) // https://www.arduino.cc/en/Reference/WireEndTransmission -byte Model01Side::setKeyscanInterval(byte delay) { +byte Model100Side::setKeyscanInterval(byte delay) { uint8_t data[] = {TWI_CMD_KEYSCAN_INTERVAL, delay}; uint8_t result = twi_writeTo(addr, data, ELEMENTS(data), 1, 0); @@ -81,18 +81,18 @@ byte Model01Side::setKeyscanInterval(byte delay) { // returns -1 on error, otherwise returns the scanner version integer -int Model01Side::readVersion() { +int Model100Side::readVersion() { return readRegister(TWI_CMD_VERSION); } // returns -1 on error, otherwise returns the scanner keyscan interval -int Model01Side::readKeyscanInterval() { +int Model100Side::readKeyscanInterval() { return readRegister(TWI_CMD_KEYSCAN_INTERVAL); } // returns -1 on error, otherwise returns the LED SPI Frequncy -int Model01Side::readLEDSPIFrequency() { +int Model100Side::readLEDSPIFrequency() { return readRegister(TWI_CMD_LED_SPI_FREQUENCY); } @@ -101,7 +101,7 @@ int Model01Side::readLEDSPIFrequency() { // // returns the Wire.endTransmission code (0 = success) // https://www.arduino.cc/en/Reference/WireEndTransmission -byte Model01Side::setLEDSPIFrequency(byte frequency) { +byte Model100Side::setLEDSPIFrequency(byte frequency) { uint8_t data[] = {TWI_CMD_LED_SPI_FREQUENCY, frequency}; uint8_t result = twi_writeTo(addr, data, ELEMENTS(data), 1, 0); @@ -110,7 +110,7 @@ byte Model01Side::setLEDSPIFrequency(byte frequency) { -int Model01Side::readRegister(uint8_t cmd) { +int Model100Side::readRegister(uint8_t cmd) { byte return_value = 0; @@ -138,7 +138,7 @@ int Model01Side::readRegister(uint8_t cmd) { // gives information on the key that was just pressed or released. -bool Model01Side::readKeys() { +bool Model100Side::readKeys() { uint8_t rxBuffer[5]; @@ -155,11 +155,11 @@ bool Model01Side::readKeys() { } } -keydata_t Model01Side::getKeyData() { +keydata_t Model100Side::getKeyData() { return keyData; } -void Model01Side::sendLEDData() { +void Model100Side::sendLEDData() { sendLEDBank(nextLEDBank++); if (nextLEDBank == LED_BANKS) { nextLEDBank = 0; @@ -168,7 +168,7 @@ void Model01Side::sendLEDData() { auto constexpr gamma8 = kaleidoscope::driver::color::gamma_correction; -void Model01Side::sendLEDBank(byte bank) { +void Model100Side::sendLEDBank(byte bank) { uint8_t data[LED_BYTES_PER_BANK + 1]; data[0] = TWI_CMD_LED_BASE + bank; for (uint8_t i = 0 ; i < LED_BYTES_PER_BANK; i++) { @@ -187,7 +187,7 @@ void Model01Side::sendLEDBank(byte bank) { uint8_t result = twi_writeTo(addr, data, ELEMENTS(data), 1, 0); } -void Model01Side::setAllLEDsTo(cRGB color) { +void Model100Side::setAllLEDsTo(cRGB color) { uint8_t data[] = {TWI_CMD_LED_SET_ALL_TO, pgm_read_byte(&gamma8[color.b]), pgm_read_byte(&gamma8[color.g]), @@ -196,7 +196,7 @@ void Model01Side::setAllLEDsTo(cRGB color) { uint8_t result = twi_writeTo(addr, data, ELEMENTS(data), 1, 0); } -void Model01Side::setOneLEDTo(byte led, cRGB color) { +void Model100Side::setOneLEDTo(byte led, cRGB color) { uint8_t data[] = {TWI_CMD_LED_SET_ONE_TO, led, pgm_read_byte(&gamma8[color.b]), diff --git a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model01Side.h b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model100Side.h similarity index 93% rename from plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model01Side.h rename to plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model100Side.h index 1e1743f3..1841095b 100644 --- a/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model01Side.h +++ b/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/driver/keyboardio/Model100Side.h @@ -1,6 +1,6 @@ // -*- mode: c++ -*- -/* kaleidoscope::driver::keyboardio::Model01Side - * Copyright (C) 2015-2020 Keyboard.io, Inc +/* kaleidoscope::driver::keyboardio::Model100Side + * Copyright (C) 2021 Keyboard.io, Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -60,10 +60,10 @@ typedef union { #ifndef KALEIDOSCOPE_VIRTUAL_BUILD // used to configure interrupts, configuration for a particular controller -class Model01Side { +class Model100Side { public: - explicit Model01Side(byte setAd01); - ~Model01Side() {} + explicit Model100Side(byte setAd01); + ~Model100Side() {} int readVersion(); @@ -98,7 +98,7 @@ class Model01Side { int readRegister(uint8_t cmd); }; #else // ifndef KALEIDOSCOPE_VIRTUAL_BUILD -class Model01Side; +class Model100Side; #endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD } // namespace keyboardio