Add HAN pullup config and mosquito board

This commit is contained in:
david-beinder 2023-03-12 00:17:07 +01:00
parent 938f9f69d1
commit 35d47902c6
No known key found for this signature in database
10 changed files with 98 additions and 23 deletions

View File

@ -4,7 +4,7 @@
#include "Arduino.h"
#define EEPROM_SIZE 1024*3
#define EEPROM_CHECK_SUM 102 // Used to check if config is stored. Change if structure changes
#define EEPROM_CHECK_SUM 103 // Used to check if config is stored. Change if structure changes
#define EEPROM_CLEARED_INDICATOR 0xFC
#define EEPROM_CONFIG_ADDRESS 0
#define EEPROM_TEMP_CONFIG_ADDRESS 2048
@ -141,7 +141,8 @@ struct GpioConfig {
uint8_t vccBootLimit;
uint16_t vccResistorGnd;
uint16_t vccResistorVcc;
}; // 20
bool hanPinPullup;
}; // 21
struct DomoticzConfig {
uint16_t elidx;
@ -304,6 +305,7 @@ private:
bool relocateConfig96(); // 2.1.14
bool relocateConfig100(); // 2.2-dev
bool relocateConfig101(); // 2.2.0 through 2.2.8
bool relocateConfig102(); // 2.2.9
void saveToFs();
bool loadFromFs(uint8_t version);

View File

@ -374,6 +374,7 @@ bool AmsConfiguration::setGpioConfig(GpioConfig& config) {
GpioConfig existing;
if(getGpioConfig(existing)) {
meterChanged |= config.hanPin != existing.hanPin;
meterChanged |= config.hanPinPullup != existing.hanPinPullup;
}
/* This currently does not work, as it checks its own pin
if(pinUsed(config.hanPin, config)) {
@ -425,6 +426,7 @@ bool AmsConfiguration::setGpioConfig(GpioConfig& config) {
void AmsConfiguration::clearGpio(GpioConfig& config) {
config.hanPin = 3;
config.hanPinPullup = true;
config.apPin = 0xFF;
config.ledPin = 0xFF;
config.ledInverted = true;
@ -764,6 +766,14 @@ bool AmsConfiguration::hasConfig() {
configVersion = 0;
return false;
}
case 102:
configVersion = -1; // Prevent loop
if(relocateConfig102()) {
configVersion = 103;
} else {
configVersion = 0;
return false;
}
case EEPROM_CHECK_SUM:
return true;
default:
@ -985,6 +995,20 @@ bool AmsConfiguration::relocateConfig101() {
return ret;
}
bool AmsConfiguration::relocateConfig102() {
EEPROM.begin(EEPROM_SIZE);
GpioConfig gpioConfig;
EEPROM.get(CONFIG_GPIO_START, gpioConfig);
gpioConfig.hanPinPullup = true;
EEPROM.put(CONFIG_GPIO_START, gpioConfig);
EEPROM.put(EEPROM_CONFIG_ADDRESS, 103);
bool ret = EEPROM.commit();
EEPROM.end();
return ret;
}
bool AmsConfiguration::save() {
EEPROM.begin(EEPROM_SIZE);
EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_CHECK_SUM);
@ -1139,6 +1163,7 @@ void AmsConfiguration::print(Print* debugger)
if(getGpioConfig(gpio)) {
debugger->println("--GPIO configuration--");
debugger->printf("HAN pin: %i\r\n", gpio.hanPin);
debugger->printf("HAN pin pullup %s\r\n", gpio.hanPinPullup ? "Yes" : "No");
debugger->printf("LED pin: %i\r\n", gpio.ledPin);
debugger->printf("LED inverted: %s\r\n", gpio.ledInverted ? "Yes" : "No");
debugger->printf("LED red pin: %i\r\n", gpio.ledPinRed);

File diff suppressed because one or more lines are too long

View File

@ -42,6 +42,9 @@
</optgroup>
{/if}
{#if chip == 'esp32c3'}
<optgroup label="Custom hardware">
<option value={8}>{boardtype(chip, 8)}</option>
</optgroup>
<optgroup label="Generic hardware">
<option value={71}>{boardtype(chip, 71)}</option>
<option value={70}>{boardtype(chip, 70)}</option>

View File

@ -88,7 +88,8 @@
i: 0, e: 0, v: 0, a: 0, r: 0, c: 0, t: 0, p: 0, d: 0, m: 0, s: 0
},
i: {
h: null, a: null,
h: { p: null, u: true },
a: null,
l: { p: null, i: false },
r: { r: null, g: null, b: null, i: false },
t: { d: null, a: null },
@ -577,8 +578,8 @@
<input type="hidden" name="i" value="true"/>
<div class="flex flex-wrap">
<div class="w-1/3">
HAN<br/>
<select name="ih" bind:value={configuration.i.h} class="in-f w-full">
HAN<label class="ml-2"><input name="ihu" value="true" bind:checked={configuration.i.h.u} type="checkbox" class="rounded mb-1"/> pullup</label><br/>
<select name="ihp" bind:value={configuration.i.h.p} class="in-f w-full">
<UartSelectOptions chip={sysinfo.chip}/>
</select>
</div>

View File

@ -87,6 +87,8 @@ export function boardtype(c, b) {
return "Custom hardware by Roar Fredriksen";
case 1:
return "Kamstrup module by Egil Opsahl"
case 8:
return "µHAN mosquito by dbeinder"
case 3:
return "Pow-K (UART0)";
case 4:

View File

@ -1,13 +1,21 @@
<script>
export let chip;
let gpioMax = 44;
let gpioMax = 39;
$: {
gpioMax = chip == 'esp8266' ? 16 : chip == 'esp32s2' ? 44 : 39;
switch (chip) {
case 'esp8266': gpioMax = 16; break;
case 'esp32s2': gpioMax = 44; break;
case 'esp32c3': gpioMax = 19; break;
}
}
</script>
{#if chip == 'esp32c3'}
<option value={20}>UART0</option>
{:else}
<option value={3}>UART0</option>
{/if}
{#if chip == 'esp8266'}
<option value={113}>UART2</option>
{/if}

View File

@ -1,5 +1,8 @@
"i": {
"h": %s,
"h": {
"p": %s,
"u": %s
},
"a": %s,
"l": {
"p": %s,

View File

@ -895,6 +895,7 @@ void AmsWebServer::configurationJson() {
server.sendContent(buf);
snprintf_P(buf, BufferSize, CONF_GPIO_JSON,
gpioConfig->hanPin == 0xff ? "null" : String(gpioConfig->hanPin, 10).c_str(),
gpioConfig->hanPinPullup ? "true" : "false",
gpioConfig->apPin == 0xff ? "null" : String(gpioConfig->apPin, 10).c_str(),
gpioConfig->ledPin == 0xff ? "null" : String(gpioConfig->ledPin, 10).c_str(),
gpioConfig->ledInverted ? "true" : "false",
@ -977,6 +978,15 @@ void AmsWebServer::handleSave() {
}
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
switch(boardType) {
case 8: // dbeinder: HAN mosquito
gpioConfig->hanPin = 7;
gpioConfig->hanPinPullup = false;
gpioConfig->apPin = 9;
gpioConfig->ledRgbInverted = true;
gpioConfig->ledPinRed = 5;
gpioConfig->ledPinGreen = 6;
gpioConfig->ledPinBlue = 4;
break;
case 71: // ESP32-C3-DevKitM-1
gpioConfig->apPin = 9;
case 70: // Generic ESP32-C3
@ -1113,6 +1123,7 @@ void AmsWebServer::handleSave() {
meterConfig->baud = 2400;
meterConfig->parity = 3; // 8N1
case 2: // spenceme
case 8: // dbeinder: HAN mosquito
case 50: // Generic ESP32-S2
case 51: // Wemos S2 mini
case 70: // Generic ESP32-C3
@ -1287,7 +1298,8 @@ void AmsWebServer::handleSave() {
if(server.hasArg(F("i")) && server.arg(F("i")) == F("true")) {
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Received GPIO config"));
gpioConfig->hanPin = server.hasArg(F("ih")) && !server.arg(F("ih")).isEmpty() ? server.arg(F("ih")).toInt() : 3;
gpioConfig->hanPin = server.hasArg(F("ihp")) && !server.arg(F("ihp")).isEmpty() ? server.arg(F("ihp")).toInt() : 3;
gpioConfig->hanPinPullup = server.hasArg(F("ihu")) && server.arg(F("ihu")) == F("true");
gpioConfig->ledPin = server.hasArg(F("ilp")) && !server.arg(F("ilp")).isEmpty() ? server.arg(F("ilp")).toInt() : 0xFF;
gpioConfig->ledInverted = server.hasArg(F("ili")) && server.arg(F("ili")) == F("true");
gpioConfig->ledPinRed = server.hasArg(F("irr")) && !server.arg(F("irr")).isEmpty() ? server.arg(F("irr")).toInt() : 0xFF;
@ -1939,6 +1951,7 @@ void AmsWebServer::configFileDownload() {
GpioConfig gpio;
config->getGpioConfig(gpio);
if(gpio.hanPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioHanPin %d\n"), gpio.hanPin));
if(gpio.hanPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioHanPinPullup %d\n"), gpio.hanPinPullup ? 1 : 0));
if(gpio.apPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioApPin %d\n"), gpio.apPin));
if(gpio.ledPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedPin %d\n"), gpio.ledPin));
if(gpio.ledPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedInverted %d\n"), gpio.ledInverted ? 1 : 0));

View File

@ -563,7 +563,7 @@ void loop() {
if(config.isMeterChanged()) {
config.getMeterConfig(meterConfig);
setupHanPort(gpioConfig.hanPin, meterConfig.baud, meterConfig.parity, meterConfig.invert);
setupHanPort(gpioConfig, meterConfig.baud, meterConfig.parity, meterConfig.invert);
config.ackMeterChanged();
delete gcmParser;
gcmParser = NULL;
@ -606,7 +606,7 @@ void loop() {
meterAutoIndex++; // Default is to try the first one in setup()
debugI("Meter serial autodetect, swapping to: %d, %d, %s", bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex] ? "true" : "false");
if(meterAutoIndex >= 4) meterAutoIndex = 0;
setupHanPort(gpioConfig.hanPin, bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex]);
setupHanPort(gpioConfig, bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex]);
meterAutodetectLastChange = now;
}
} else if(meterAutodetect) {
@ -616,7 +616,7 @@ void loop() {
meterConfig.parity = parities[meterAutoIndex];
meterConfig.invert = inverts[meterAutoIndex];
config.setMeterConfig(meterConfig);
setupHanPort(gpioConfig.hanPin, meterConfig.baud, meterConfig.parity, meterConfig.invert);
setupHanPort(gpioConfig, meterConfig.baud, meterConfig.parity, meterConfig.invert);
}
} catch(const std::exception& e) {
debugE("Exception in meter autodetect (%s)", e.what());
@ -631,7 +631,9 @@ void loop() {
#endif
}
void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert) {
void setupHanPort(GpioConfig& gpioConfig, uint32_t baud, uint8_t parityOrdinal, bool invert) {
uint8_t pin = gpioConfig.hanPin;
if(Debug.isActive(RemoteDebug::INFO)) Debug.printf((char*) F("(setupHanPort) Setting up HAN on pin %d with baud %d and parity %d\n"), pin, baud, parityOrdinal);
if(baud == 0) {
@ -643,6 +645,14 @@ void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert
parityOrdinal = 3; // 8N1
}
SystemConfig sys;
config.getSystemConfig(sys);
switch(sys.boardType) {
case 8: // HAN mosquito: has inverting level shifter
invert = !invert;
break;
}
HardwareSerial *hwSerial = NULL;
if(pin == 3 || pin == 113) {
hwSerial = &Serial;
@ -742,6 +752,11 @@ void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert
Serial.begin(115200);
}
// The library automatically sets the pullup in Serial.begin()
if(!gpioConfig.hanPinPullup) {
pinMode(gpioConfig.hanPin, INPUT);
}
// Empty buffer before starting
while (hanSerial->available() > 0) {
hanSerial->read();
@ -1602,6 +1617,9 @@ void configFileParse() {
} else if(strncmp_P(buf, PSTR("gpioHanPin "), 11) == 0) {
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
gpio.hanPin = String(buf+11).toInt();
} else if(strncmp_P(buf, PSTR("gpioHanPinPullup "), 17) == 0) {
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
gpio.hanPinPullup = String(buf+17).toInt() == 1;
} else if(strncmp_P(buf, PSTR("gpioApPin "), 10) == 0) {
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
gpio.apPin = String(buf+10).toInt();