From 996404ceed0496034b8f9b9650c384f909d7a35e Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Tue, 28 Mar 2023 23:46:07 +0200 Subject: [PATCH] Introduce gpio2 for the CMT2300A module This implements the sending interrupt instead of polling. On the other hand, gpio3 is made optional. --- docs/DeviceProfiles.md | 3 +- include/PinMapping.h | 1 + lib/CMT2300a/cmt2300wrapper.cpp | 2 +- lib/Hoymiles/src/Hoymiles.cpp | 4 +-- lib/Hoymiles/src/Hoymiles.h | 2 +- lib/Hoymiles/src/HoymilesRadio_CMT.cpp | 41 +++++++++++++++++++++----- lib/Hoymiles/src/HoymilesRadio_CMT.h | 9 ++++-- src/InverterSettings.cpp | 2 +- src/PinMapping.cpp | 7 ++++- src/WebApi_device.cpp | 1 + webapp/src/types/PinMapping.ts | 1 + 11 files changed, 56 insertions(+), 17 deletions(-) diff --git a/docs/DeviceProfiles.md b/docs/DeviceProfiles.md index 7d67692..5e4a708 100644 --- a/docs/DeviceProfiles.md +++ b/docs/DeviceProfiles.md @@ -95,7 +95,8 @@ The json file can contain multiple profiles. Each profile requires a name and di | cmt.clk | number | CLK Pin | | cmt.cs | number | CS Pin | | cmt.fcs | number | FCS Pin | -| cmt.gpio3 | number | GPIO3 Pin | +| cmt.gpio2 | number | GPIO2 Pin (optional) | +| cmt.gpio3 | number | GPIO3 Pin (optional) | | eth.enabled | boolean | Enable/Disable the ethernet stack | | eth.phy_addr | number | Unique PHY addr | | eth.power | number | Power Pin (if available). Use -1 for not assigned pins. | diff --git a/include/PinMapping.h b/include/PinMapping.h index df8bb78..2360a67 100644 --- a/include/PinMapping.h +++ b/include/PinMapping.h @@ -22,6 +22,7 @@ struct PinMapping_t { int8_t cmt_clk; int8_t cmt_cs; int8_t cmt_fcs; + int8_t cmt_gpio2; int8_t cmt_gpio3; int8_t cmt_sdio; diff --git a/lib/CMT2300a/cmt2300wrapper.cpp b/lib/CMT2300a/cmt2300wrapper.cpp index 99c70eb..539630e 100644 --- a/lib/CMT2300a/cmt2300wrapper.cpp +++ b/lib/CMT2300a/cmt2300wrapper.cpp @@ -166,7 +166,7 @@ bool CMT2300A::_init_radio() /* Config GPIOs */ CMT2300A_ConfigGpio( - CMT2300A_GPIO3_SEL_INT2); + CMT2300A_GPIO2_SEL_INT1 | CMT2300A_GPIO3_SEL_INT2); /* Config interrupt */ CMT2300A_ConfigInterrupt( diff --git a/lib/Hoymiles/src/Hoymiles.cpp b/lib/Hoymiles/src/Hoymiles.cpp index 68ce797..7bb26b6 100644 --- a/lib/Hoymiles/src/Hoymiles.cpp +++ b/lib/Hoymiles/src/Hoymiles.cpp @@ -32,9 +32,9 @@ void HoymilesClass::initNRF(SPIClass* initialisedSpiBus, uint8_t pinCE, uint8_t _radioNrf->init(initialisedSpiBus, pinCE, pinIRQ); } -void HoymilesClass::initCMT(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, int8_t pin_gpio3) +void HoymilesClass::initCMT(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, int8_t pin_gpio2, int8_t pin_gpio3) { - _radioCmt->init(pin_sdio, pin_clk, pin_cs, pin_fcs, pin_gpio3); + _radioCmt->init(pin_sdio, pin_clk, pin_cs, pin_fcs, pin_gpio2, pin_gpio3); } void HoymilesClass::loop() diff --git a/lib/Hoymiles/src/Hoymiles.h b/lib/Hoymiles/src/Hoymiles.h index 7863183..66bc0c1 100644 --- a/lib/Hoymiles/src/Hoymiles.h +++ b/lib/Hoymiles/src/Hoymiles.h @@ -17,7 +17,7 @@ class HoymilesClass { public: void init(); void initNRF(SPIClass* initialisedSpiBus, uint8_t pinCE, uint8_t pinIRQ); - void initCMT(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, int8_t pin_gpio3); + void initCMT(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, int8_t pin_gpio2, int8_t pin_gpio3); void loop(); void setMessageOutput(Print* output); diff --git a/lib/Hoymiles/src/HoymilesRadio_CMT.cpp b/lib/Hoymiles/src/HoymilesRadio_CMT.cpp index 54d13d9..1fb5356 100644 --- a/lib/Hoymiles/src/HoymilesRadio_CMT.cpp +++ b/lib/Hoymiles/src/HoymilesRadio_CMT.cpp @@ -119,10 +119,16 @@ enumCMTresult HoymilesRadio_CMT::cmtProcess(void) break; case CMT_STATE_RX_WAIT: - if (_packetReceived) /* Read INT2, PKT_OK */ + if (!_gpio3_configured) { + if (CMT2300A_MASK_PKT_OK_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG)) { // read INT2, PKT_OK flag + _packetReceived = true; + } + } + + if (_packetReceived) { - Hoymiles.getMessageOutput()->println("Interrupt received"); - _packetReceived = false; // reset interrupt + Hoymiles.getMessageOutput()->println("Interrupt 2 received"); + _packetReceived = false; // reset interrupt 2 cmtNextState = CMT_STATE_RX_DONE; } @@ -223,8 +229,14 @@ enumCMTresult HoymilesRadio_CMT::cmtProcess(void) break; case CMT_STATE_TX_WAIT: - if (CMT2300A_MASK_TX_DONE_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_CLR1)) /* Read TX_DONE flag */ - { + if (!_gpio2_configured) { + if (CMT2300A_MASK_TX_DONE_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_CLR1)) { // read INT1, TX_DONE flag + _packetSent = true; + } + } + if (_packetSent) { + Hoymiles.getMessageOutput()->println(F("Interrupt 1 received")); + _packetSent = false; // reset interrupt 1 cmtNextState = CMT_STATE_TX_DONE; } @@ -283,7 +295,7 @@ enumCMTresult HoymilesRadio_CMT::cmtProcess(void) return nRes; } -void HoymilesRadio_CMT::init(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, int8_t pin_gpio3) +void HoymilesRadio_CMT::init(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, int8_t pin_gpio2, int8_t pin_gpio3) { _dtuSerial.u64 = 0; @@ -301,7 +313,15 @@ void HoymilesRadio_CMT::init(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int Hoymiles.getMessageOutput()->println("Connection error!!"); } - attachInterrupt(digitalPinToInterrupt(pin_gpio3), std::bind(&HoymilesRadio_CMT::handleIntr, this), RISING); + if (pin_gpio2 >= 0) { + attachInterrupt(digitalPinToInterrupt(pin_gpio2), std::bind(&HoymilesRadio_CMT::handleInt1, this), RISING); + _gpio2_configured = true; + } + + if (pin_gpio3 >= 0) { + attachInterrupt(digitalPinToInterrupt(pin_gpio3), std::bind(&HoymilesRadio_CMT::handleInt2, this), RISING); + _gpio3_configured = true; + } _isInitialized = true; } @@ -423,7 +443,12 @@ bool HoymilesRadio_CMT::isConnected() return _radio->isChipConnected(); } -void ARDUINO_ISR_ATTR HoymilesRadio_CMT::handleIntr() +void ARDUINO_ISR_ATTR HoymilesRadio_CMT::handleInt1() +{ + _packetSent = true; +} + +void ARDUINO_ISR_ATTR HoymilesRadio_CMT::handleInt2() { _packetReceived = true; } diff --git a/lib/Hoymiles/src/HoymilesRadio_CMT.h b/lib/Hoymiles/src/HoymilesRadio_CMT.h index b78a560..177165a 100644 --- a/lib/Hoymiles/src/HoymilesRadio_CMT.h +++ b/lib/Hoymiles/src/HoymilesRadio_CMT.h @@ -40,20 +40,25 @@ typedef enum { class HoymilesRadio_CMT : public HoymilesRadio { public: - void init(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, int8_t pin_gpio3); + void init(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, int8_t pin_gpio2, int8_t pin_gpio3); void loop(); void setPALevel(int8_t paLevel); bool isConnected(); private: - void ARDUINO_ISR_ATTR handleIntr(); + void ARDUINO_ISR_ATTR handleInt1(); + void ARDUINO_ISR_ATTR handleInt2(); void sendEsbPacket(CommandAbstract* cmd); std::unique_ptr _radio; volatile bool _packetReceived = false; + volatile bool _packetSent = false; + + bool _gpio2_configured = false; + bool _gpio3_configured = false; std::queue _rxBuffer; TimeoutHelper _rxTimeout; diff --git a/src/InverterSettings.cpp b/src/InverterSettings.cpp index d4a8e57..835e7bc 100644 --- a/src/InverterSettings.cpp +++ b/src/InverterSettings.cpp @@ -33,7 +33,7 @@ void InverterSettingsClass::init() } if (PinMapping.isValidCmt2300Config()) { - Hoymiles.initCMT(pin.cmt_sdio, pin.cmt_clk, pin.cmt_cs, pin.cmt_fcs, pin.cmt_gpio3); + Hoymiles.initCMT(pin.cmt_sdio, pin.cmt_clk, pin.cmt_cs, pin.cmt_fcs, pin.cmt_gpio2, pin.cmt_gpio3); } MessageOutput.println(" Setting radio PA level... "); diff --git a/src/PinMapping.cpp b/src/PinMapping.cpp index c62dc03..9cbcd87 100644 --- a/src/PinMapping.cpp +++ b/src/PinMapping.cpp @@ -50,6 +50,10 @@ #define CMT_FCS -1 #endif +#ifndef CMT_GPIO2 +#define CMT_GPIO2 -1 +#endif + #ifndef CMT_GPIO3 #define CMT_GPIO3 -1 #endif @@ -73,6 +77,7 @@ PinMappingClass::PinMappingClass() _pinMapping.cmt_clk = CMT_CLK; _pinMapping.cmt_cs = CMT_CS; _pinMapping.cmt_fcs = CMT_FCS; + _pinMapping.cmt_gpio2 = CMT_GPIO2; _pinMapping.cmt_gpio3 = CMT_GPIO3; _pinMapping.cmt_sdio = CMT_SDIO; @@ -133,6 +138,7 @@ bool PinMappingClass::init(const String& deviceMapping) _pinMapping.cmt_clk = doc[i]["cmt"]["clk"] | CMT_CLK; _pinMapping.cmt_cs = doc[i]["cmt"]["cs"] | CMT_CS; _pinMapping.cmt_fcs = doc[i]["cmt"]["fcs"] | CMT_FCS; + _pinMapping.cmt_gpio2 = doc[i]["cmt"]["gpio2"] | CMT_GPIO2; _pinMapping.cmt_gpio3 = doc[i]["cmt"]["gpio3"] | CMT_GPIO3; _pinMapping.cmt_sdio = doc[i]["cmt"]["sdio"] | CMT_SDIO; @@ -180,7 +186,6 @@ bool PinMappingClass::isValidCmt2300Config() return _pinMapping.cmt_clk >= 0 && _pinMapping.cmt_cs >= 0 && _pinMapping.cmt_fcs >= 0 - && _pinMapping.cmt_gpio3 >= 0 && _pinMapping.cmt_sdio >= 0; } diff --git a/src/WebApi_device.cpp b/src/WebApi_device.cpp index e149455..0903bee 100644 --- a/src/WebApi_device.cpp +++ b/src/WebApi_device.cpp @@ -52,6 +52,7 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request) cmtPinObj["cs"] = pin.cmt_cs; cmtPinObj["fcs"] = pin.cmt_fcs; cmtPinObj["sdio"] = pin.cmt_sdio; + cmtPinObj["gpio2"] = pin.cmt_gpio2; cmtPinObj["gpio3"] = pin.cmt_gpio3; JsonObject ethPinObj = curPin.createNestedObject("eth"); diff --git a/webapp/src/types/PinMapping.ts b/webapp/src/types/PinMapping.ts index 1170872..0f5492c 100644 --- a/webapp/src/types/PinMapping.ts +++ b/webapp/src/types/PinMapping.ts @@ -12,6 +12,7 @@ export interface Cmt2300 { cs: number; fcs: number; sdio: number; + gpio2: number; gpio3: number; }