better i2c protocol implentation
This commit is contained in:
+103
-61
@@ -937,78 +937,48 @@ uint8_t crc8(const uint8_t *data, size_t len) {
|
|||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void total_pc_control() {
|
bool execute_pc_command(uint8_t *data, uint8_t *&p, uint8_t *output, uint8_t len, uint32_t* baud_change) {
|
||||||
static uint8_t data[127];
|
|
||||||
static uint8_t output[257];
|
|
||||||
uint8_t *p = output + 2;
|
|
||||||
uint32_t baud_change = 0;
|
|
||||||
|
|
||||||
if(i2c_pc_control_init) {
|
|
||||||
Serial.write(1);
|
|
||||||
Serial.write(0xff);
|
|
||||||
Serial.flush();
|
|
||||||
i2c_pc_control_init = false;
|
|
||||||
}
|
|
||||||
if(Serial.available()) {
|
|
||||||
uint8_t userlen = Serial.read();
|
|
||||||
if (userlen == 0) return;
|
|
||||||
|
|
||||||
if(Serial.available() && userlen == '~' && Serial.peek() == '/') {
|
|
||||||
Serial.read();
|
|
||||||
Serial.write(1);
|
|
||||||
Serial.write(0xff);
|
|
||||||
Serial.flush(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool has_crc = (userlen >> 7) == 1;
|
|
||||||
uint8_t orig_userlen = userlen;
|
|
||||||
userlen &= 127;
|
|
||||||
|
|
||||||
auto len = Serial.read(data, userlen);
|
|
||||||
if(len != userlen) return;
|
|
||||||
|
|
||||||
if(has_crc && Serial.available()) {
|
|
||||||
uint8_t crc = Serial.read();
|
|
||||||
|
|
||||||
uint8_t expected_crc = 0;
|
|
||||||
expected_crc = crc8_update(expected_crc, orig_userlen);
|
|
||||||
for (int i = 0; i < len; i++) expected_crc = crc8_update(expected_crc, data[i]);
|
|
||||||
if(crc != expected_crc) {
|
|
||||||
Serial.write(0x02);
|
|
||||||
Serial.write(0xFF);
|
|
||||||
Serial.write(0x01);
|
|
||||||
Serial.flush();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (data[0]) {
|
switch (data[0]) {
|
||||||
case 0: { // Set clock
|
case 0: { // Set clock
|
||||||
if(len < 5) return;
|
if(len < 5) {
|
||||||
|
*p++ = 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
uint32_t clock = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 8) | ((uint32_t)data[4]);
|
uint32_t clock = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 8) | ((uint32_t)data[4]);
|
||||||
Wire.setClock(clock);
|
Wire.setClock(clock);
|
||||||
} break;
|
} break;
|
||||||
case 1: { // Send data
|
case 1: { // Send data
|
||||||
if(len < 3) return;
|
if(len < 3) {
|
||||||
|
*p++ = 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
Wire.beginTransmission(data[1]);
|
Wire.beginTransmission(data[1]);
|
||||||
Wire.write(data + 2, len - 2);
|
Wire.write(data + 2, len - 2);
|
||||||
auto out = Wire.endTransmission();
|
auto out = Wire.endTransmission();
|
||||||
*p++ = out;
|
*p++ = out;
|
||||||
} break;
|
} break;
|
||||||
case 2: { // Send and receive data
|
case 2: { // Send and receive data
|
||||||
if(len < 4) return; // Need at least: cmd, addr, datalen, recvlen
|
if(len < 4) {
|
||||||
|
*p++ = 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
uint8_t addr = data[1];
|
uint8_t addr = data[1];
|
||||||
uint8_t datalen = data[2];
|
uint8_t datalen = data[2];
|
||||||
|
|
||||||
if(len < 3 + datalen + 1) return; // Validate buffer size
|
if(len < 3 + datalen + 1) {
|
||||||
|
*p++ = 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Wire.beginTransmission(addr);
|
Wire.beginTransmission(addr);
|
||||||
Wire.write(data + 3, datalen);
|
Wire.write(data + 3, datalen);
|
||||||
auto out = Wire.endTransmission(false);
|
auto out = Wire.endTransmission(false);
|
||||||
|
|
||||||
uint8_t recvlen = Wire.requestFrom(addr, data[3+datalen]);
|
uint8_t recvlen = Wire.requestFrom(addr, data[3+datalen]);
|
||||||
if ((p - output) + recvlen >= sizeof(output)) return;
|
if ((p - output) + recvlen >= sizeof(output)) {
|
||||||
|
*p++ = 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
*p++ = out;
|
*p++ = out;
|
||||||
while(Wire.available()) *p++ = Wire.read();
|
while(Wire.available()) *p++ = Wire.read();
|
||||||
@@ -1016,10 +986,10 @@ void total_pc_control() {
|
|||||||
case 3: { // Quit
|
case 3: { // Quit
|
||||||
i2c_pc_control = false;
|
i2c_pc_control = false;
|
||||||
MuteScreen(false);
|
MuteScreen(false);
|
||||||
baud_change = 115200;
|
*baud_change = 115200;
|
||||||
} break;
|
} break;
|
||||||
case 4: { // Version
|
case 4: { // Version
|
||||||
*p++ = 2;
|
*p++ = 3;
|
||||||
} break;
|
} break;
|
||||||
case 5: { // Reboot
|
case 5: { // Reboot
|
||||||
Serial.write(1);
|
Serial.write(1);
|
||||||
@@ -1028,17 +998,26 @@ void total_pc_control() {
|
|||||||
esp_restart();
|
esp_restart();
|
||||||
} break;
|
} break;
|
||||||
case 6: { // Change baud
|
case 6: { // Change baud
|
||||||
if(len < 5) return;
|
if(len < 5) {
|
||||||
baud_change = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) |
|
*p++ = 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*baud_change = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) |
|
||||||
((uint32_t)data[3] << 8) | ((uint32_t)data[4]);
|
((uint32_t)data[3] << 8) | ((uint32_t)data[4]);
|
||||||
} break;
|
} break;
|
||||||
case 7: { // Write to EEPROM
|
case 7: { // Write to EEPROM
|
||||||
if(len < 4) return;
|
if(len < 4) {
|
||||||
|
*p++ = 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
EEPROM.writeBytes((data[1] << 8) | data[2], data + 3, len - 3);
|
EEPROM.writeBytes((data[1] << 8) | data[2], data + 3, len - 3);
|
||||||
EEPROM.commit();
|
EEPROM.commit();
|
||||||
} break;
|
} break;
|
||||||
case 8: { // Read from EEPROM
|
case 8: { // Read from EEPROM
|
||||||
if(len < 4) return;
|
if(len < 4) {
|
||||||
|
*p++ = 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
auto address = (data[1] << 8) | data[2];
|
auto address = (data[1] << 8) | data[2];
|
||||||
*p++ = data[3] + 1;
|
*p++ = data[3] + 1;
|
||||||
*p++ = 8;
|
*p++ = 8;
|
||||||
@@ -1055,13 +1034,76 @@ void total_pc_control() {
|
|||||||
*p++ = EE_BYTE_CONTROLMODE & 0xff;
|
*p++ = EE_BYTE_CONTROLMODE & 0xff;
|
||||||
} break;
|
} break;
|
||||||
case 0xff:
|
case 0xff:
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
*p++ = 3;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void total_pc_control() {
|
||||||
|
static uint8_t data[127];
|
||||||
|
static uint8_t output[257];
|
||||||
|
uint8_t *p = output + 2;
|
||||||
|
uint32_t baud_change = 0;
|
||||||
|
bool error = false;
|
||||||
|
bool done = false;
|
||||||
|
bool send_crc = false;
|
||||||
|
|
||||||
|
if(i2c_pc_control_init) {
|
||||||
|
error = true;
|
||||||
|
done = true;
|
||||||
|
i2c_pc_control_init = false;
|
||||||
|
}
|
||||||
|
if(Serial.available() && !done) {
|
||||||
|
uint8_t userlen = Serial.read();
|
||||||
|
if (userlen == 0) {
|
||||||
|
Serial.flush();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Serial.available() && userlen == '~' && Serial.peek() == '/') {
|
||||||
|
Serial.read();
|
||||||
|
error = true;
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!done) {
|
||||||
|
bool has_crc = (userlen >> 7) == 1;
|
||||||
|
send_crc = has_crc;
|
||||||
|
uint8_t orig_userlen = userlen;
|
||||||
|
userlen &= 127;
|
||||||
|
|
||||||
|
auto len = Serial.read(data, userlen);
|
||||||
|
if(len != userlen) {
|
||||||
|
error = true;
|
||||||
|
*p++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(has_crc && Serial.available()) {
|
||||||
|
uint8_t crc = Serial.read();
|
||||||
|
|
||||||
|
uint8_t expected_crc = 0;
|
||||||
|
expected_crc = crc8_update(expected_crc, orig_userlen);
|
||||||
|
for (int i = 0; i < len; i++) expected_crc = crc8_update(expected_crc, data[i]);
|
||||||
|
if(crc != expected_crc) {
|
||||||
|
error = true;
|
||||||
|
send_crc = false;
|
||||||
|
*p++ = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!error) error = execute_pc_command(data, p, output, len, &baud_change);
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(done) {
|
||||||
output[0] = (p - output) - 1;
|
output[0] = (p - output) - 1;
|
||||||
output[1] = data[0];
|
if(error) output[1] = 0xff;
|
||||||
if(has_crc) {
|
else output[1] = data[0];
|
||||||
|
|
||||||
|
if(send_crc) {
|
||||||
output[0] |= 0x80;
|
output[0] |= 0x80;
|
||||||
uint8_t crc = crc8(output, p - output);
|
uint8_t crc = crc8(output, p - output);
|
||||||
*p++ = crc;
|
*p++ = crc;
|
||||||
@@ -1075,6 +1117,6 @@ void total_pc_control() {
|
|||||||
baud_change = 0;
|
baud_change = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.flush(true);
|
Serial.flush(!error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user