Start to implement "suspend a missing device"

f/keyboardio-model-100
Jesse Vincent 3 years ago
parent 40e40cd868
commit b44edf476b
No known key found for this signature in database
GPG Key ID: 122F5DF7108E4046

@ -103,23 +103,67 @@ byte Model100Side::setLEDSPIFrequency(byte frequency) {
} }
// GD32 I2C implements timeouts which will cause a stall when a device does not answer.
// This method will verify that the device is around and ready to talk.
bool Model100Side::isDeviceAvailable() {
// if we dont know the device is around,
return true;
// if the counter is zero, that's the special value that means "we know it's there"
if (unavailable_device_check_countdown_ == 0) {
return true;
}
// if the time to check counter is 1, check for the device
else if ( --unavailable_device_check_countdown_ == 0 ) {
uint8_t wire_result;
Wire.beginTransmission(addr);
wire_result = Wire.endTransmission();
//if the check succeeds
if (wire_result == 0) {
unavailable_device_check_countdown_ = 0; // TODO this is already true
return true;
} else {
Wire.beginTransmission (wire_result);
wire_result = Wire.endTransmission();
// set the time to check counter to max
unavailable_device_check_countdown_ = UNAVAILABLE_DEVICE_COUNTDOWN_MAX;
return false;
}
} else {
// we've decremented the counter, but it's not time to probe for the device yet.
return false;
}
}
void Model100Side::markDeviceUnavailable() {
unavailable_device_check_countdown_ = 1; // We think there was a comms problem. Check on the next cycle
}
uint8_t Model100Side::writeData(uint8_t *data, uint8_t length) { uint8_t Model100Side::writeData(uint8_t *data, uint8_t length) {
if (isDeviceAvailable() == false ) {
return 1;
}
Wire.beginTransmission(addr); Wire.beginTransmission(addr);
Wire.write(data, length); Wire.write(data, length);
uint8_t result = Wire.endTransmission(); uint8_t result = Wire.endTransmission();
if (result) { markDeviceUnavailable(); }
return result; return result;
} }
int Model100Side::readRegister(uint8_t cmd) { int Model100Side::readRegister(uint8_t cmd) {
byte return_value = 0; byte return_value = 0;
uint8_t data[] = {cmd}; uint8_t data[] = {cmd};
uint8_t result = writeData(data, ELEMENTS(data)); uint8_t result = writeData(data, ELEMENTS(data));
// If the setup failed, return. This means there was a problem asking for the register
if (result) {
return -1;
}
delayMicroseconds(15); // TODO We may be able to drop this in the future
delayMicroseconds(15); // We may be able to drop this in the future
// but will need to verify with correctly // but will need to verify with correctly
// sized pull-ups on both the left and right // sized pull-ups on both the left and right
// hands' i2c SDA and SCL lines // hands' i2c SDA and SCL lines
@ -132,6 +176,7 @@ int Model100Side::readRegister(uint8_t cmd) {
if (Wire.available()) { if (Wire.available()) {
return Wire.read(); return Wire.read();
} else { } else {
//markDeviceUnavailable();
return -1; return -1;
} }
@ -140,15 +185,21 @@ int Model100Side::readRegister(uint8_t cmd) {
// gives information on the key that was just pressed or released. // gives information on the key that was just pressed or released.
bool Model100Side::readKeys() { bool Model100Side::readKeys() {
if (isDeviceAvailable() == false ) {
return false;
}
uint8_t row_counter = 0; uint8_t row_counter = 0;
// perform blocking read into buffer // perform blocking read into buffer
uint8_t read = 0; uint8_t read = 0;
Wire.requestFrom(addr, 5); // request 1 byte from the keyscanner uint8_t bytes_returned =0;
bytes_returned = Wire.requestFrom(addr, 5); // request 5 bytes from the keyscanner
if (bytes_returned < 5) {
return false;
}
if (Wire.available()) { if (Wire.available()) {
read = Wire.read(); read = Wire.read();
if (TWI_REPLY_KEYDATA == read) { if (TWI_REPLY_KEYDATA == read) {
while (Wire.available()) { while (Wire.available()) {
keyData.rows[row_counter++] = Wire.read(); keyData.rows[row_counter++] = Wire.read();
} }

@ -78,9 +78,12 @@ class Model100Side {
void setAllLEDsTo(cRGB color); void setAllLEDsTo(cRGB color);
keydata_t getKeyData(); keydata_t getKeyData();
bool readKeys(); bool readKeys();
LEDData_t ledData; LEDData_t ledData;
uint8_t controllerAddress();
uint8_t controllerAddress();
bool isDeviceAvailable();
void markDeviceUnavailable();
void setBrightness(uint8_t brightness) { void setBrightness(uint8_t brightness) {
brightness_adjustment_ = 255 - brightness; brightness_adjustment_ = 255 - brightness;
} }
@ -93,6 +96,10 @@ class Model100Side {
int addr; int addr;
int ad01; int ad01;
keydata_t keyData; keydata_t keyData;
// a value of 0 is "device seen" - anything else is how many cycles before we should
// check for the device
uint16_t unavailable_device_check_countdown_ = 1;
static const uint16_t UNAVAILABLE_DEVICE_COUNTDOWN_MAX = 0xFFFFU;
byte nextLEDBank = 0; byte nextLEDBank = 0;
void sendLEDBank(byte bank); void sendLEDBank(byte bank);
int readRegister(uint8_t cmd); int readRegister(uint8_t cmd);

Loading…
Cancel
Save