Merge pull request #481 from dbeinder/mosquito

Add HAN pullup config and mosquito board
This commit is contained in:
Gunnar Skjold 2023-04-01 07:43:34 +02:00 committed by GitHub
commit 18dc188835
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 88 additions and 13 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
@ -142,7 +142,8 @@ struct GpioConfig {
uint8_t vccBootLimit;
uint16_t vccResistorGnd;
uint16_t vccResistorVcc;
}; // 20
bool hanPinPullup;
}; // 21
struct DomoticzConfig {
uint16_t elidx;
@ -314,6 +315,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

@ -406,6 +406,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)) {
@ -457,6 +458,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;
@ -796,6 +798,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:
@ -1017,6 +1027,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);
@ -1171,6 +1195,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);

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 },
@ -599,8 +600,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

@ -913,6 +913,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",
@ -1001,6 +1002,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
@ -1137,6 +1147,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
@ -1329,7 +1340,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;
@ -1996,6 +2008,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

@ -564,7 +564,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;
@ -607,7 +607,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) {
@ -617,7 +617,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());
@ -632,7 +632,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) {
@ -644,6 +646,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;
@ -743,6 +753,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();
@ -1621,6 +1636,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();