You've already forked TEF6686_ESP32
i2c raw control
This commit is contained in:
53
i2c_protocol.py
Normal file
53
i2c_protocol.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import serial
|
||||||
|
import struct
|
||||||
|
import time
|
||||||
|
|
||||||
|
class I2CPCClient:
|
||||||
|
def __init__(self, port, baudrate=115200, timeout=1):
|
||||||
|
self.ser = serial.Serial(port=port, baudrate=baudrate, timeout=timeout)
|
||||||
|
self.ser.write(b"~/")
|
||||||
|
self.ser.flush()
|
||||||
|
while not ((d := self.ser.read_all()) and b"\x01\xff" in d): pass
|
||||||
|
|
||||||
|
def _send_packet(self, payload: bytes):
|
||||||
|
length = len(payload)
|
||||||
|
self.ser.write(bytes([length]) + payload)
|
||||||
|
|
||||||
|
# Read response length
|
||||||
|
resp_len_raw = self.ser.read(1)
|
||||||
|
if not resp_len_raw:
|
||||||
|
raise TimeoutError("Error")
|
||||||
|
|
||||||
|
resp_len = resp_len_raw[0]
|
||||||
|
response = self.ser.read(resp_len)
|
||||||
|
|
||||||
|
if len(response) != resp_len: raise TimeoutError("Incomplete response")
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
def set_clock(self, clock_hz: int):
|
||||||
|
payload = bytes([0]) + struct.pack(">I", clock_hz)
|
||||||
|
return self._send_packet(payload)
|
||||||
|
|
||||||
|
def write_i2c(self, addr: int, data: bytes):
|
||||||
|
payload = bytes([1, addr]) + data
|
||||||
|
return self._send_packet(payload)
|
||||||
|
|
||||||
|
def write_read_i2c(self, addr: int, write_data: bytes, read_len: int):
|
||||||
|
payload = bytes([2, addr, len(write_data)]) + write_data + bytes([read_len])
|
||||||
|
return self._send_packet(payload)
|
||||||
|
|
||||||
|
def version(self): return self._send_packet(bytes([4]))
|
||||||
|
|
||||||
|
def quit(self): return self._send_packet(bytes([3]))
|
||||||
|
|
||||||
|
def reboot(self): return self._send_packet(bytes([5]))
|
||||||
|
|
||||||
|
def set_baudrate(self, baud: int):
|
||||||
|
payload = bytes([6]) + struct.pack(">I", baud)
|
||||||
|
out = self._send_packet(payload)
|
||||||
|
self.ser.baudrate = baud
|
||||||
|
return out
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.ser.close()
|
||||||
@@ -9,6 +9,7 @@ void Communication();
|
|||||||
void XDRGTKRoutine();
|
void XDRGTKRoutine();
|
||||||
void passwordcrypt();
|
void passwordcrypt();
|
||||||
void tryWiFi();
|
void tryWiFi();
|
||||||
|
void total_pc_control();
|
||||||
|
|
||||||
extern void BuildDisplay();
|
extern void BuildDisplay();
|
||||||
extern void BuildAdvancedRDS();
|
extern void BuildAdvancedRDS();
|
||||||
|
|||||||
@@ -336,6 +336,9 @@ extern bool rds_settings_changed;
|
|||||||
extern const size_t language_totalnumber;
|
extern const size_t language_totalnumber;
|
||||||
extern const size_t language_entrynumber;
|
extern const size_t language_entrynumber;
|
||||||
|
|
||||||
|
extern volatile bool i2c_pc_control;
|
||||||
|
extern volatile bool i2c_pc_control_init;
|
||||||
|
|
||||||
extern mem presets[EE_PRESETS_CNT];
|
extern mem presets[EE_PRESETS_CNT];
|
||||||
extern TEF6686 radio;
|
extern TEF6686 radio;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <TFT_eSPI.h>
|
#include <TFT_eSPI.h>
|
||||||
|
|
||||||
|
#define CONSOLE_FONT 2
|
||||||
|
|
||||||
class Console {
|
class Console {
|
||||||
public:
|
public:
|
||||||
explicit Console(TFT_eSPI* display) : tft(display), y(0) {}
|
explicit Console(TFT_eSPI* display) : tft(display), y(0) {}
|
||||||
@@ -9,9 +11,9 @@ public:
|
|||||||
tft->setTextColor(TFT_WHITE, background);
|
tft->setTextColor(TFT_WHITE, background);
|
||||||
tft->setTextDatum(TL_DATUM);
|
tft->setTextDatum(TL_DATUM);
|
||||||
auto data = "[" + String(millis() / 1000.0f) + "] " + text;
|
auto data = "[" + String(millis() / 1000.0f) + "] " + text;
|
||||||
tft->fillRect(0, y, tft->textWidth(data), tft->fontHeight(2), background);
|
tft->fillRect(0, y, tft->textWidth(data, CONSOLE_FONT), tft->fontHeight(CONSOLE_FONT), background);
|
||||||
tft->drawString(data, 0, y, 2);
|
tft->drawString(data, 0, y, CONSOLE_FONT);
|
||||||
y += tft->fontHeight(2);
|
y += tft->fontHeight(CONSOLE_FONT);
|
||||||
}
|
}
|
||||||
void reset() {
|
void reset() {
|
||||||
y = 0;
|
y = 0;
|
||||||
|
|||||||
106
src/comms.cpp
106
src/comms.cpp
@@ -359,6 +359,11 @@ void Communication() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (data_str.startsWith("l") || data_str.startsWith("L")) printLogbookCSV();
|
} else if (data_str.startsWith("l") || data_str.startsWith("L")) printLogbookCSV();
|
||||||
|
else if(data_str.charAt(0) == '~' && data_str.charAt(1) == '/') {
|
||||||
|
MuteScreen(true);
|
||||||
|
i2c_pc_control = i2c_pc_control_init = true;
|
||||||
|
Serial.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RDSSPYUSB && Serial.available()) {
|
if (RDSSPYUSB && Serial.available()) {
|
||||||
@@ -915,4 +920,105 @@ void tryWiFi() {
|
|||||||
Udp.stop();
|
Udp.stop();
|
||||||
WiFi.mode(WIFI_OFF);
|
WiFi.mode(WIFI_OFF);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void total_pc_control() {
|
||||||
|
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 == '~' && Serial.read() == '/') {
|
||||||
|
Serial.write(1);
|
||||||
|
Serial.write(0xff);
|
||||||
|
Serial.flush(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *data = (uint8_t*)malloc(userlen);
|
||||||
|
if(data == NULL) return;
|
||||||
|
auto len = Serial.read(data, userlen);
|
||||||
|
if(len != userlen) {
|
||||||
|
free(data);
|
||||||
|
return; // Incomplete data
|
||||||
|
}
|
||||||
|
switch (data[0]) {
|
||||||
|
case 0: { // Set clock
|
||||||
|
if(len < 5) break;
|
||||||
|
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);
|
||||||
|
Serial.write(1);
|
||||||
|
Serial.write(0);
|
||||||
|
} break;
|
||||||
|
case 1: { // Send data
|
||||||
|
if(len < 3) break;
|
||||||
|
Wire.beginTransmission(data[1]);
|
||||||
|
for(int i = 0; i < (len-2); i++) Wire.write(data[2+i]);
|
||||||
|
auto out = Wire.endTransmission();
|
||||||
|
Serial.write(2);
|
||||||
|
Serial.write(1);
|
||||||
|
Serial.write(out);
|
||||||
|
} break;
|
||||||
|
case 2: { // Send and receive data
|
||||||
|
if(len < 4) break; // Need at least: cmd, addr, datalen, recvlen
|
||||||
|
uint8_t addr = data[1];
|
||||||
|
uint8_t datalen = data[2];
|
||||||
|
|
||||||
|
if(len < 3 + datalen + 1) break; // Validate buffer size
|
||||||
|
|
||||||
|
Wire.beginTransmission(addr);
|
||||||
|
for(int i = 0; i < datalen; i++) Wire.write(data[3+i]);
|
||||||
|
auto out = Wire.endTransmission(false);
|
||||||
|
|
||||||
|
uint8_t recvlen_requested = data[3+datalen];
|
||||||
|
uint8_t recvlen = Wire.requestFrom(addr, recvlen_requested);
|
||||||
|
|
||||||
|
Serial.write(recvlen+2);
|
||||||
|
Serial.write(2);
|
||||||
|
Serial.write(out);
|
||||||
|
while(Wire.available()) Serial.write(Wire.read());
|
||||||
|
} break;
|
||||||
|
case 3: { // Quit
|
||||||
|
i2c_pc_control = false;
|
||||||
|
MuteScreen(false);
|
||||||
|
Serial.write(1);
|
||||||
|
Serial.write(3);
|
||||||
|
Serial.flush();
|
||||||
|
Serial.updateBaudRate(115200);
|
||||||
|
} break;
|
||||||
|
case 4: { // Version
|
||||||
|
Serial.write(2);
|
||||||
|
Serial.write(4);
|
||||||
|
Serial.write(0);
|
||||||
|
} break;
|
||||||
|
case 5: { // Reboot
|
||||||
|
Serial.write(1);
|
||||||
|
Serial.write(5);
|
||||||
|
Serial.flush();
|
||||||
|
delay(5);
|
||||||
|
esp_restart();
|
||||||
|
} break;
|
||||||
|
case 6: { // Change baud
|
||||||
|
if(len < 5) break;
|
||||||
|
uint32_t clock = ((uint32_t)data[1] << 24) |
|
||||||
|
((uint32_t)data[2] << 16) |
|
||||||
|
((uint32_t)data[3] << 8) |
|
||||||
|
((uint32_t)data[4]);
|
||||||
|
Serial.write(1);
|
||||||
|
Serial.write(6);
|
||||||
|
Serial.flush(true);
|
||||||
|
Serial.updateBaudRate(clock);
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(data);
|
||||||
|
Serial.flush(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -324,6 +324,9 @@ bool rds_settings_changed;
|
|||||||
const size_t language_totalnumber = sizeof(myLanguage) / sizeof(myLanguage[0]);
|
const size_t language_totalnumber = sizeof(myLanguage) / sizeof(myLanguage[0]);
|
||||||
const size_t language_entrynumber = sizeof(myLanguage[0]) / sizeof(myLanguage[0][0]);
|
const size_t language_entrynumber = sizeof(myLanguage[0]) / sizeof(myLanguage[0][0]);
|
||||||
|
|
||||||
|
volatile bool i2c_pc_control = false;
|
||||||
|
volatile bool i2c_pc_control_init = false;
|
||||||
|
|
||||||
mem presets[EE_PRESETS_CNT];
|
mem presets[EE_PRESETS_CNT];
|
||||||
TEF6686 radio;
|
TEF6686 radio;
|
||||||
TFT_eSPI tft = TFT_eSPI();
|
TFT_eSPI tft = TFT_eSPI();
|
||||||
|
|||||||
14
src/main.cpp
14
src/main.cpp
@@ -1130,7 +1130,7 @@ void endMenu() {
|
|||||||
if (af == 2) radio.rds.afreg = true; else radio.rds.afreg = false;
|
if (af == 2) radio.rds.afreg = true; else radio.rds.afreg = false;
|
||||||
Serial.end();
|
Serial.end();
|
||||||
if (wifi) remoteip = IPAddress (WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], subnetclient);
|
if (wifi) remoteip = IPAddress (WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], subnetclient);
|
||||||
if (USBmode) Serial.begin(19200); else Serial.begin(115200);
|
if (USBmode) Serial.updateBaudRate(19200); else Serial.updateBaudRate(115200);
|
||||||
|
|
||||||
leave = true;
|
leave = true;
|
||||||
if (language == LANGUAGE_CHS) PSSprite.setTextFont(3); else PSSprite.setTextFont(2);
|
if (language == LANGUAGE_CHS) PSSprite.setTextFont(3); else PSSprite.setTextFont(2);
|
||||||
@@ -1202,7 +1202,6 @@ void MuteScreen(bool setting) {
|
|||||||
|
|
||||||
void setup_periph() {
|
void setup_periph() {
|
||||||
Wire.setClock(400000);
|
Wire.setClock(400000);
|
||||||
Serial.begin(115200);
|
|
||||||
Serial.println();
|
Serial.println();
|
||||||
byte error, address;
|
byte error, address;
|
||||||
for (address = 1; address < 108; address++) {
|
for (address = 1; address < 108; address++) {
|
||||||
@@ -1232,7 +1231,6 @@ void setup_periph() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
Serial.end();
|
|
||||||
|
|
||||||
Wire.setClock(100000);
|
Wire.setClock(100000);
|
||||||
}
|
}
|
||||||
@@ -1305,7 +1303,7 @@ void later_setup_periph() {
|
|||||||
} else console.print("RX8010SJ is not available at address " + String(RX8010SJ_ADDRESS, HEX));
|
} else console.print("RX8010SJ is not available at address " + String(RX8010SJ_ADDRESS, HEX));
|
||||||
|
|
||||||
if(analogRead(BATTERY_PIN) < BATTERY_DETECT_THRESHOLD) batterydetect = false;
|
if(analogRead(BATTERY_PIN) < BATTERY_DETECT_THRESHOLD) batterydetect = false;
|
||||||
else console.print("Battery detected.");
|
else console.print("Battery detected");
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_encoder();
|
void read_encoder();
|
||||||
@@ -1325,6 +1323,7 @@ void setup() {
|
|||||||
EEPROM.begin(EE_TOTAL_CNT);
|
EEPROM.begin(EE_TOTAL_CNT);
|
||||||
|
|
||||||
setupmode = true;
|
setupmode = true;
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
Wire.begin();
|
Wire.begin();
|
||||||
Wire.setClock(100000);
|
Wire.setClock(100000);
|
||||||
@@ -1355,7 +1354,7 @@ void setup() {
|
|||||||
for (int y = 0; y < 5; y++) presets[i].RDSPI[y] = EEPROM.readByte((i * 5) + y + EE_PRESETS_RDSPI_START);
|
for (int y = 0; y < 5; y++) presets[i].RDSPI[y] = EEPROM.readByte((i * 5) + y + EE_PRESETS_RDSPI_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (USBmode) Serial.begin(19200); else Serial.begin(115200);
|
if (USBmode) Serial.updateBaudRate(19200); else Serial.updateBaudRate(115200);
|
||||||
|
|
||||||
if (iMSset && EQset) iMSEQ = 2;
|
if (iMSset && EQset) iMSEQ = 2;
|
||||||
if (!iMSset && EQset) iMSEQ = 3;
|
if (!iMSset && EQset) iMSEQ = 3;
|
||||||
@@ -1633,6 +1632,11 @@ void handleTimers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
if(i2c_pc_control) {
|
||||||
|
total_pc_control();
|
||||||
|
if(i2c_pc_control) return;
|
||||||
|
}
|
||||||
|
|
||||||
handleWiFi();
|
handleWiFi();
|
||||||
handleTouch();
|
handleTouch();
|
||||||
Communication();
|
Communication();
|
||||||
|
|||||||
Reference in New Issue
Block a user