Allow dynamic pin mapping for CMT module
This commit is contained in:
parent
3c0d89f599
commit
45882543b6
@ -91,6 +91,11 @@ The json file can contain multiple profiles. Each profile requires a name and di
|
||||
| nrf24.irq | number | Interrupt Pin |
|
||||
| nrf24.en | number | Enable Pin |
|
||||
| nrf24.cs | number | Chip Select Pin |
|
||||
| cmt.sdio | number | SDIO Pin |
|
||||
| cmt.clk | number | CLK Pin |
|
||||
| cmt.cs | number | CS Pin |
|
||||
| cmt.fcs | number | FCS Pin |
|
||||
| cmt.gpio3 | number | GPIO3 Pin |
|
||||
| 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. |
|
||||
|
||||
@ -18,6 +18,13 @@ struct PinMapping_t {
|
||||
int8_t nrf24_irq;
|
||||
int8_t nrf24_en;
|
||||
int8_t nrf24_cs;
|
||||
|
||||
int8_t cmt_clk;
|
||||
int8_t cmt_cs;
|
||||
int8_t cmt_fcs;
|
||||
int8_t cmt_gpio3;
|
||||
int8_t cmt_sdio;
|
||||
|
||||
int8_t eth_phy_addr;
|
||||
bool eth_enabled;
|
||||
int eth_power;
|
||||
@ -40,6 +47,7 @@ public:
|
||||
PinMapping_t& get();
|
||||
|
||||
bool isValidNrf24Config();
|
||||
bool isValidCmt2300Config();
|
||||
bool isValidEthConfig();
|
||||
|
||||
private:
|
||||
|
||||
@ -26,9 +26,9 @@
|
||||
* @name CMT2300A_InitSpi
|
||||
* @desc Initializes the CMT2300A SPI interface.
|
||||
* *********************************************************/
|
||||
void CMT2300A_InitSpi(void)
|
||||
void CMT2300A_InitSpi(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs)
|
||||
{
|
||||
cmt_spi3_init();
|
||||
cmt_spi3_init(pin_sdio, pin_clk, pin_cs, pin_fcs);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
|
||||
@ -36,7 +36,7 @@ extern "C" {
|
||||
#define CMT2300A_GetTickCount() millis()
|
||||
/* ************************************************************************ */
|
||||
|
||||
void CMT2300A_InitSpi(void);
|
||||
void CMT2300A_InitSpi(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs);
|
||||
|
||||
uint8_t CMT2300A_ReadReg(uint8_t addr);
|
||||
void CMT2300A_WriteReg(uint8_t addr, uint8_t dat);
|
||||
|
||||
@ -7,12 +7,12 @@
|
||||
|
||||
spi_device_handle_t spi_reg, spi_fifo;
|
||||
|
||||
void cmt_spi3_init(void)
|
||||
void cmt_spi3_init(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs)
|
||||
{
|
||||
spi_bus_config_t buscfg = {
|
||||
.mosi_io_num = CMT_PIN_SDIO,
|
||||
.mosi_io_num = pin_sdio,
|
||||
.miso_io_num = -1, // single wire MOSI/MISO
|
||||
.sclk_io_num = CMT_PIN_CLK,
|
||||
.sclk_io_num = pin_clk,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
.max_transfer_sz = 32,
|
||||
@ -23,7 +23,7 @@ void cmt_spi3_init(void)
|
||||
.dummy_bits = 0,
|
||||
.mode = 0, // SPI mode 0
|
||||
.clock_speed_hz = CMT_SPI_CLK,
|
||||
.spics_io_num = CMT_PIN_CS,
|
||||
.spics_io_num = pin_cs,
|
||||
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
|
||||
.queue_size = 1,
|
||||
.pre_cb = NULL,
|
||||
@ -42,7 +42,7 @@ void cmt_spi3_init(void)
|
||||
.cs_ena_pretrans = 2,
|
||||
.cs_ena_posttrans = (uint8_t)(1 / (CMT_SPI_CLK * 10e6 * 2) + 2), // >2 us
|
||||
.clock_speed_hz = CMT_SPI_CLK,
|
||||
.spics_io_num = CMT_PIN_FCS,
|
||||
.spics_io_num = pin_fcs,
|
||||
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
|
||||
.queue_size = 1,
|
||||
.pre_cb = NULL,
|
||||
@ -50,7 +50,7 @@ void cmt_spi3_init(void)
|
||||
};
|
||||
ESP_ERROR_CHECK(spi_bus_add_device(SPI2_HOST, &devcfg2, &spi_fifo));
|
||||
|
||||
esp_rom_gpio_connect_out_signal(CMT_PIN_SDIO, spi_periph_signal[SPI2_HOST].spid_out, true, false);
|
||||
esp_rom_gpio_connect_out_signal(pin_sdio, spi_periph_signal[SPI2_HOST].spid_out, true, false);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void cmt_spi3_init(void);
|
||||
void cmt_spi3_init(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs);
|
||||
|
||||
void cmt_spi3_write(uint8_t addr, uint8_t dat);
|
||||
uint8_t cmt_spi3_read(uint8_t addr);
|
||||
|
||||
@ -3,12 +3,12 @@
|
||||
* Copyright (C) 2022 Thomas Basler and others
|
||||
*/
|
||||
#include "Hoymiles.h"
|
||||
#include "inverters/HM_1CH.h"
|
||||
#include "inverters/HM_2CH.h"
|
||||
#include "inverters/HM_4CH.h"
|
||||
#include "inverters/HMS_1CH.h"
|
||||
#include "inverters/HMS_2CH.h"
|
||||
#include "inverters/HMS_4CH.h"
|
||||
#include "inverters/HM_1CH.h"
|
||||
#include "inverters/HM_2CH.h"
|
||||
#include "inverters/HM_4CH.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
#define HOY_SEMAPHORE_TAKE() xSemaphoreTake(_xSemaphore, portMAX_DELAY)
|
||||
@ -16,32 +16,49 @@
|
||||
|
||||
HoymilesClass Hoymiles;
|
||||
|
||||
void HoymilesClass::init(SPIClass* initialisedSpiBus, uint8_t pinCE, uint8_t pinIRQ)
|
||||
void HoymilesClass::init()
|
||||
{
|
||||
_xSemaphore = xSemaphoreCreateMutex();
|
||||
HOY_SEMAPHORE_GIVE(); // release before first use
|
||||
|
||||
_pollInterval = 0;
|
||||
_radioNrf.reset(new HoymilesRadio_NRF());
|
||||
_radioNrf->init(initialisedSpiBus, pinCE, pinIRQ);
|
||||
|
||||
_radioCmt.reset(new HoymilesRadio_CMT());
|
||||
_radioCmt->init();
|
||||
}
|
||||
|
||||
void HoymilesClass::initNRF(SPIClass* initialisedSpiBus, uint8_t pinCE, uint8_t pinIRQ)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
_radioCmt->init(pin_sdio, pin_clk, pin_cs, pin_fcs, pin_gpio3);
|
||||
}
|
||||
|
||||
void HoymilesClass::loop()
|
||||
{
|
||||
HOY_SEMAPHORE_TAKE();
|
||||
if (_radioNrf->isInitialized()) {
|
||||
_radioNrf->loop();
|
||||
}
|
||||
|
||||
if (_radioCmt->isInitialized()) {
|
||||
_radioCmt->loop();
|
||||
}
|
||||
|
||||
if (getNumInverters() > 0) {
|
||||
if (millis() - _lastPoll > (_pollInterval * 1000)) {
|
||||
static uint8_t inverterPos = 0;
|
||||
|
||||
if (_radioNrf->isIdle() && _radioCmt->isIdle()) {
|
||||
std::shared_ptr<InverterAbstract> iv = getInverterByPos(inverterPos);
|
||||
if (iv != nullptr) {
|
||||
if ((iv == nullptr) || ((iv != nullptr) && (!iv->getRadio()->isInitialized()))) {
|
||||
if (++inverterPos >= getNumInverters()) {
|
||||
inverterPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (iv != nullptr && iv->getRadio()->isInitialized() && iv->getRadio()->isIdle()) {
|
||||
_messageOutput->print("Fetch inverter: ");
|
||||
_messageOutput->println(iv->serial(), HEX);
|
||||
|
||||
@ -76,15 +93,15 @@ void HoymilesClass::loop()
|
||||
_messageOutput->println("Request device info");
|
||||
iv->sendDevInfoRequest();
|
||||
}
|
||||
}
|
||||
|
||||
if (++inverterPos >= getNumInverters()) {
|
||||
inverterPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_lastPoll = millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HOY_SEMAPHORE_GIVE();
|
||||
}
|
||||
|
||||
@ -15,7 +15,9 @@
|
||||
|
||||
class HoymilesClass {
|
||||
public:
|
||||
void init(SPIClass* initialisedSpiBus, uint8_t pinCE, uint8_t pinIRQ);
|
||||
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 loop();
|
||||
|
||||
void setMessageOutput(Print* output);
|
||||
|
||||
@ -62,3 +62,13 @@ void HoymilesRadio::dumpBuf(const char* info, uint8_t buf[], uint8_t len)
|
||||
}
|
||||
Hoymiles.getMessageOutput()->println("");
|
||||
}
|
||||
|
||||
bool HoymilesRadio::isInitialized()
|
||||
{
|
||||
return _isInitialized;
|
||||
}
|
||||
|
||||
bool HoymilesRadio::isIdle()
|
||||
{
|
||||
return !_busyFlag;
|
||||
}
|
||||
@ -11,6 +11,9 @@ public:
|
||||
serial_u DtuSerial();
|
||||
virtual void setDtuSerial(uint64_t serial);
|
||||
|
||||
bool isIdle();
|
||||
bool isInitialized();
|
||||
|
||||
template <typename T>
|
||||
T* enqueCommand()
|
||||
{
|
||||
@ -29,4 +32,6 @@ protected:
|
||||
|
||||
serial_u _dtuSerial;
|
||||
std::queue<std::shared_ptr<CommandAbstract>> _commandQueue;
|
||||
bool _isInitialized = false;
|
||||
bool _busyFlag = false;
|
||||
};
|
||||
@ -222,7 +222,7 @@ enumCMTresult HoymilesRadio_CMT::cmtProcess(void)
|
||||
cmtRxTimeoutCnt++;
|
||||
} else {
|
||||
uint32_t invSerial = cmtTxBuffer[1] << 24 | cmtTxBuffer[2] << 16 | cmtTxBuffer[3] << 8 | cmtTxBuffer[4]; // read inverter serial from last Tx buffer
|
||||
cmtSwitchInvAndDtuFreq(invSerial, HOY_BOOT_FREQ / 1000, CMT_WORK_FREQ);
|
||||
cmtSwitchInvAndDtuFreq(invSerial, HOY_BOOT_FREQ / 1000, HOYMILES_CMT_WORK_FREQ);
|
||||
}
|
||||
|
||||
nRes = CMT_RX_TIMEOUT;
|
||||
@ -315,12 +315,12 @@ enumCMTresult HoymilesRadio_CMT::cmtProcess(void)
|
||||
return nRes;
|
||||
}
|
||||
|
||||
void HoymilesRadio_CMT::init()
|
||||
void HoymilesRadio_CMT::init(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, int8_t pin_gpio3)
|
||||
{
|
||||
_dtuSerial.u64 = 0;
|
||||
uint8_t tmp;
|
||||
|
||||
CMT2300A_InitSpi();
|
||||
CMT2300A_InitSpi(pin_sdio, pin_clk, pin_cs, pin_fcs);
|
||||
if (!CMT2300A_Init()) {
|
||||
Hoymiles.getMessageOutput()->println("CMT2300A_Init() failed!");
|
||||
return;
|
||||
@ -345,11 +345,12 @@ void HoymilesRadio_CMT::init()
|
||||
return;
|
||||
}
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(CMT_PIN_GPIO3), std::bind(&HoymilesRadio_CMT::handleIntr, this), RISING);
|
||||
attachInterrupt(digitalPinToInterrupt(pin_gpio3), std::bind(&HoymilesRadio_CMT::handleIntr, this), RISING);
|
||||
|
||||
cmtSwitchDtuFreq(CMT_WORK_FREQ); // start dtu at work freqency, for fast Rx if inverter is already on and frequency switched
|
||||
cmtSwitchDtuFreq(HOYMILES_CMT_WORK_FREQ); // start dtu at work freqency, for fast Rx if inverter is already on and frequency switched
|
||||
|
||||
_ChipConnected = true;
|
||||
_isInitialized = true;
|
||||
|
||||
Hoymiles.getMessageOutput()->println("CMT init successful");
|
||||
}
|
||||
@ -447,11 +448,6 @@ void HoymilesRadio_CMT::loop()
|
||||
}
|
||||
}
|
||||
|
||||
bool HoymilesRadio_CMT::isIdle()
|
||||
{
|
||||
return !_busyFlag;
|
||||
}
|
||||
|
||||
bool HoymilesRadio_CMT::isConnected()
|
||||
{
|
||||
return _ChipConnected;
|
||||
|
||||
@ -39,10 +39,9 @@ typedef enum {
|
||||
|
||||
class HoymilesRadio_CMT : public HoymilesRadio {
|
||||
public:
|
||||
void init();
|
||||
void init(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, int8_t pin_gpio3);
|
||||
void loop();
|
||||
|
||||
bool isIdle();
|
||||
bool isConnected();
|
||||
|
||||
private:
|
||||
@ -55,8 +54,6 @@ private:
|
||||
std::queue<fragment_t> _rxBuffer;
|
||||
TimeoutHelper _rxTimeout;
|
||||
|
||||
bool _busyFlag = false;
|
||||
|
||||
bool _ChipConnected = false;
|
||||
|
||||
String cmtChToFreq(const uint8_t channel);
|
||||
|
||||
@ -33,6 +33,7 @@ void HoymilesRadio_NRF::init(SPIClass* initialisedSpiBus, uint8_t pinCE, uint8_t
|
||||
|
||||
openReadingPipe();
|
||||
_radio->startListening();
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
void HoymilesRadio_NRF::loop()
|
||||
@ -159,11 +160,6 @@ void HoymilesRadio_NRF::setDtuSerial(uint64_t serial)
|
||||
openReadingPipe();
|
||||
}
|
||||
|
||||
bool HoymilesRadio_NRF::isIdle()
|
||||
{
|
||||
return !_busyFlag;
|
||||
}
|
||||
|
||||
bool HoymilesRadio_NRF::isConnected()
|
||||
{
|
||||
return _radio->isChipConnected();
|
||||
|
||||
@ -20,7 +20,6 @@ public:
|
||||
|
||||
virtual void setDtuSerial(uint64_t serial);
|
||||
|
||||
bool isIdle();
|
||||
bool isConnected();
|
||||
bool isPVariant();
|
||||
|
||||
@ -46,6 +45,4 @@ private:
|
||||
|
||||
std::queue<fragment_t> _rxBuffer;
|
||||
TimeoutHelper _rxTimeout;
|
||||
|
||||
bool _busyFlag = false;
|
||||
};
|
||||
@ -96,6 +96,11 @@ bool InverterAbstract::getEnableCommands()
|
||||
return _enableCommands;
|
||||
}
|
||||
|
||||
HoymilesRadio* InverterAbstract::getRadio()
|
||||
{
|
||||
return _radio;
|
||||
}
|
||||
|
||||
AlarmLogParser* InverterAbstract::EventLog()
|
||||
{
|
||||
return _alarmLogParser.get();
|
||||
|
||||
@ -64,6 +64,8 @@ public:
|
||||
virtual bool sendRestartControlRequest() = 0;
|
||||
virtual bool resendPowerControlRequest() = 0;
|
||||
|
||||
HoymilesRadio* getRadio();
|
||||
|
||||
AlarmLogParser* EventLog();
|
||||
DevInfoParser* DevInfo();
|
||||
PowerCommandParser* PowerCommand();
|
||||
|
||||
@ -56,12 +56,7 @@ build_flags = ${env.build_flags}
|
||||
-DHOYMILES_PIN_IRQ=16
|
||||
-DHOYMILES_PIN_CE=4
|
||||
-DHOYMILES_PIN_CS=5
|
||||
-DCMT_PIN_CLK=18
|
||||
-DCMT_PIN_SDIO=23
|
||||
-DCMT_PIN_CS=5
|
||||
-DCMT_PIN_FCS=4
|
||||
-DCMT_PIN_GPIO3=15
|
||||
-DCMT_WORK_FREQ=865000
|
||||
-DHOYMILES_CMT_WORK_FREQ=865000
|
||||
|
||||
|
||||
[env:olimex_esp32_poe]
|
||||
|
||||
@ -22,11 +22,19 @@ void InverterSettingsClass::init()
|
||||
|
||||
// Initialize inverter communication
|
||||
MessageOutput.print("Initialize Hoymiles interface... ");
|
||||
if (PinMapping.isValidNrf24Config()) {
|
||||
if (PinMapping.isValidNrf24Config() || PinMapping.isValidCmt2300Config()) {
|
||||
SPIClass* spiClass = new SPIClass(VSPI);
|
||||
spiClass->begin(pin.nrf24_clk, pin.nrf24_miso, pin.nrf24_mosi, pin.nrf24_cs);
|
||||
Hoymiles.setMessageOutput(&MessageOutput);
|
||||
Hoymiles.init(spiClass, pin.nrf24_en, pin.nrf24_irq);
|
||||
Hoymiles.init();
|
||||
|
||||
if (PinMapping.isValidNrf24Config()) {
|
||||
Hoymiles.initNRF(spiClass, pin.nrf24_en, pin.nrf24_irq);
|
||||
}
|
||||
|
||||
if (PinMapping.isValidCmt2300Config()) {
|
||||
Hoymiles.initCMT(pin.cmt_sdio, pin.cmt_clk, pin.cmt_cs, pin.cmt_fcs, pin.cmt_gpio3);
|
||||
}
|
||||
|
||||
MessageOutput.println(" Setting radio PA level... ");
|
||||
Hoymiles.getRadioNrf()->setPALevel((rf24_pa_dbm_e)config.Dtu_PaLevel);
|
||||
|
||||
@ -38,6 +38,26 @@
|
||||
#define LED1 -1
|
||||
#endif
|
||||
|
||||
#ifndef CMT_CLK
|
||||
#define CMT_CLK -1
|
||||
#endif
|
||||
|
||||
#ifndef CMT_CS
|
||||
#define CMT_CS -1
|
||||
#endif
|
||||
|
||||
#ifndef CMT_FCS
|
||||
#define CMT_FCS -1
|
||||
#endif
|
||||
|
||||
#ifndef CMT_GPIO3
|
||||
#define CMT_GPIO3 -1
|
||||
#endif
|
||||
|
||||
#ifndef CMT_SDIO
|
||||
#define CMT_SDIO -1
|
||||
#endif
|
||||
|
||||
PinMappingClass PinMapping;
|
||||
|
||||
PinMappingClass::PinMappingClass()
|
||||
@ -50,6 +70,12 @@ PinMappingClass::PinMappingClass()
|
||||
_pinMapping.nrf24_miso = HOYMILES_PIN_MISO;
|
||||
_pinMapping.nrf24_mosi = HOYMILES_PIN_MOSI;
|
||||
|
||||
_pinMapping.cmt_clk = CMT_CLK;
|
||||
_pinMapping.cmt_cs = CMT_CS;
|
||||
_pinMapping.cmt_fcs = CMT_FCS;
|
||||
_pinMapping.cmt_gpio3 = CMT_GPIO3;
|
||||
_pinMapping.cmt_sdio = CMT_SDIO;
|
||||
|
||||
#ifdef OPENDTU_ETHERNET
|
||||
_pinMapping.eth_enabled = true;
|
||||
#else
|
||||
@ -104,6 +130,12 @@ bool PinMappingClass::init(const String& deviceMapping)
|
||||
_pinMapping.nrf24_miso = doc[i]["nrf24"]["miso"] | HOYMILES_PIN_MISO;
|
||||
_pinMapping.nrf24_mosi = doc[i]["nrf24"]["mosi"] | HOYMILES_PIN_MOSI;
|
||||
|
||||
_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_gpio3 = doc[i]["cmt"]["gpio3"] | CMT_GPIO3;
|
||||
_pinMapping.cmt_sdio = doc[i]["cmt"]["sdio"] | CMT_SDIO;
|
||||
|
||||
#ifdef OPENDTU_ETHERNET
|
||||
_pinMapping.eth_enabled = doc[i]["eth"]["enabled"] | true;
|
||||
#else
|
||||
@ -143,6 +175,15 @@ bool PinMappingClass::isValidNrf24Config()
|
||||
&& _pinMapping.nrf24_mosi >= 0;
|
||||
}
|
||||
|
||||
bool PinMappingClass::isValidCmt2300Config()
|
||||
{
|
||||
return _pinMapping.cmt_clk >= 0
|
||||
&& _pinMapping.cmt_cs >= 0
|
||||
&& _pinMapping.cmt_fcs >= 0
|
||||
&& _pinMapping.cmt_gpio3 >= 0
|
||||
&& _pinMapping.cmt_sdio >= 0;
|
||||
}
|
||||
|
||||
bool PinMappingClass::isValidEthConfig()
|
||||
{
|
||||
return _pinMapping.eth_enabled;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user