diff --git a/lib/CMT2300a/cmt2300wrapper.cpp b/lib/CMT2300a/cmt2300wrapper.cpp index cf0b503..19e743b 100644 --- a/lib/CMT2300a/cmt2300wrapper.cpp +++ b/lib/CMT2300a/cmt2300wrapper.cpp @@ -245,8 +245,8 @@ bool CMT2300A::rxFifoAvailable() uint32_t CMT2300A::getBaseFrequency() { - switch (_countryMode) { - case CountryFrequency_t::MODE_900: + switch (_frequencyBand) { + case FrequencyBand_t::BAND_900: return CMT_BASE_FREQ_900; break; default: @@ -255,14 +255,14 @@ uint32_t CMT2300A::getBaseFrequency() } } -CountryFrequency_t CMT2300A::getCountryMode() const +FrequencyBand_t CMT2300A::getFrequencyBand() const { - return _countryMode; + return _frequencyBand; } -void CMT2300A::setCountryMode(const CountryFrequency_t mode) +void CMT2300A::setFrequencyBand(const FrequencyBand_t mode) { - _countryMode = mode; + _frequencyBand = mode; _init_radio(); } @@ -285,8 +285,8 @@ bool CMT2300A::_init_radio() } /* config registers */ - switch (_countryMode) { - case CountryFrequency_t::MODE_900: + switch (_frequencyBand) { + case FrequencyBand_t::BAND_900: CMT2300A_ConfigRegBank(CMT2300A_CMT_BANK_ADDR, g_cmt2300aCmtBank_900, CMT2300A_CMT_BANK_SIZE); CMT2300A_ConfigRegBank(CMT2300A_SYSTEM_BANK_ADDR, g_cmt2300aSystemBank_900, CMT2300A_SYSTEM_BANK_SIZE); CMT2300A_ConfigRegBank(CMT2300A_FREQUENCY_BANK_ADDR, g_cmt2300aFrequencyBank_900, CMT2300A_FREQUENCY_BANK_SIZE); diff --git a/lib/CMT2300a/cmt2300wrapper.h b/lib/CMT2300a/cmt2300wrapper.h index 56f25c3..d3ce1d0 100644 --- a/lib/CMT2300a/cmt2300wrapper.h +++ b/lib/CMT2300a/cmt2300wrapper.h @@ -7,10 +7,10 @@ #define FH_OFFSET 100 // value * CMT2300A_ONE_STEP_SIZE = channel frequency offset #define CMT_SPI_SPEED 4000000 // 4 MHz -enum CountryFrequency_t { - MODE_860, - MODE_900, - CountryFrequency_Max, +enum FrequencyBand_t { + BAND_860, + BAND_900, + FrequencyBand_Max, }; class CMT2300A { @@ -93,8 +93,8 @@ public: uint32_t getBaseFrequency(); - CountryFrequency_t getCountryMode() const; - void setCountryMode(const CountryFrequency_t mode); + FrequencyBand_t getFrequencyBand() const; + void setFrequencyBand(const FrequencyBand_t mode); /** * Empty the RX (receive) FIFO buffers. @@ -120,5 +120,5 @@ private: int8_t _pin_fcs; uint32_t _spi_speed; - CountryFrequency_t _countryMode = CountryFrequency_t::MODE_860; + FrequencyBand_t _frequencyBand = FrequencyBand_t::BAND_860; }; diff --git a/lib/Hoymiles/src/HoymilesRadio_CMT.cpp b/lib/Hoymiles/src/HoymilesRadio_CMT.cpp index 96dd597..d0e0b0e 100644 --- a/lib/Hoymiles/src/HoymilesRadio_CMT.cpp +++ b/lib/Hoymiles/src/HoymilesRadio_CMT.cpp @@ -6,6 +6,27 @@ #include "Hoymiles.h" #include "crc.h" #include +#include + +struct CountryFrequencyDefinition_t { + FrequencyBand_t Band; + uint32_t Freq_Legal_Min; + uint32_t Freq_Legal_Max; + uint32_t Freq_Default; + uint32_t Freq_StartUp; +}; + +constexpr CountryFrequencyDefinition_t make_value(FrequencyBand_t Band, uint32_t Freq_Legal_Min, uint32_t Freq_Legal_Max, uint32_t Freq_Default, uint32_t Freq_StartUp) +{ + CountryFrequencyDefinition_t v = { Band, Freq_Legal_Min, Freq_Legal_Max, Freq_Default, Freq_StartUp }; + return v; +} + +constexpr frozen::map countryDefinition = { + { CountryModeId_t::MODE_EU, make_value(FrequencyBand_t::BAND_860, 863e6, 870e6, 865e6, 868e6) }, + { CountryModeId_t::MODE_US, make_value(FrequencyBand_t::BAND_900, 905e6, 925e6, 915e6, 915e6) }, + { CountryModeId_t::MODE_BR, make_value(FrequencyBand_t::BAND_900, 915e6, 928e6, 915e6, 915e6) }, +}; uint32_t HoymilesRadio_CMT::getFrequencyFromChannel(const uint8_t channel) const { @@ -23,14 +44,13 @@ uint8_t HoymilesRadio_CMT::getChannelFromFrequency(const uint32_t frequency) con frequency / 1000000.0, getMinFrequency() / 1000000.0, getMaxFrequency() / 1000000.0); return 0xFF; // ERROR } - if (_radio->getCountryMode() == CountryFrequency_t::MODE_860 && (frequency < 863000000 || frequency > 870000000)) { - Hoymiles.getMessageOutput()->printf("!!! caution: %.2f MHz is out of EU legal range! (863 - 870 MHz)\r\n", - frequency / 1000000.0); - } - if (_radio->getCountryMode() == CountryFrequency_t::MODE_900 && (frequency < 902000000 || frequency > 928000000)) { - Hoymiles.getMessageOutput()->printf("!!! caution: %.2f MHz is out of North America legal range! (902 - 928 MHz)\r\n", - frequency / 1000000.0); + if (frequency < countryDefinition.at(_countryMode).Freq_Legal_Min || frequency > countryDefinition.at(_countryMode).Freq_Legal_Max) { + Hoymiles.getMessageOutput()->printf("!!! caution: %.2f MHz is out of region legal range! (%d - %d MHz)\r\n", + frequency / 1000000.0, + static_cast(countryDefinition.at(_countryMode).Freq_Legal_Min / 1e6), + static_cast(countryDefinition.at(_countryMode).Freq_Legal_Max / 1e6)); } + return (frequency - _radio->getBaseFrequency()) / getChannelWidth(); // frequency to channel } @@ -54,6 +74,7 @@ void HoymilesRadio_CMT::init(const int8_t pin_sdio, const int8_t pin_clk, const _radio->begin(); + setCountryMode(CountryModeId_t::MODE_EU); cmtSwitchDtuFreq(_inverterTargetFrequency); // start dtu at work freqency, for fast Rx if inverter is already on and frequency switched if (!_radio->isChipConnected()) { @@ -201,28 +222,21 @@ uint32_t HoymilesRadio_CMT::getChannelWidth() return FH_OFFSET * CMT2300A_ONE_STEP_SIZE; } -CountryFrequency_t HoymilesRadio_CMT::getCountryMode() const +CountryModeId_t HoymilesRadio_CMT::getCountryMode() const { - return _radio->getCountryMode(); + return _countryMode; } -void HoymilesRadio_CMT::setCountryMode(CountryFrequency_t mode) +void HoymilesRadio_CMT::setCountryMode(CountryModeId_t mode) { - _radio->setCountryMode(mode); + _radio->setFrequencyBand(countryDefinition.at(mode).Band); + _countryMode = mode; } uint32_t HoymilesRadio_CMT::getInvBootFrequency() const { // Hoymiles boot/init frequency after power up inverter or connection lost for 15 min - - switch(_radio->getCountryMode()) { - case CountryFrequency_t::MODE_900: - return 915000000; - break; - default: - return 868000000; - break; - } + return countryDefinition.at(_countryMode).Freq_StartUp; } void ARDUINO_ISR_ATTR HoymilesRadio_CMT::handleInt1() diff --git a/lib/Hoymiles/src/HoymilesRadio_CMT.h b/lib/Hoymiles/src/HoymilesRadio_CMT.h index d8c58b7..ad63d8c 100644 --- a/lib/Hoymiles/src/HoymilesRadio_CMT.h +++ b/lib/Hoymiles/src/HoymilesRadio_CMT.h @@ -16,6 +16,12 @@ #define HOYMILES_CMT_WORK_FREQ 865000000 #endif +enum CountryModeId_t { + MODE_EU, + MODE_US, + MODE_BR, +}; + class HoymilesRadio_CMT : public HoymilesRadio { public: void init(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const int8_t pin_gpio2, const int8_t pin_gpio3); @@ -30,8 +36,8 @@ public: uint32_t getMaxFrequency() const; static uint32_t getChannelWidth(); - CountryFrequency_t getCountryMode() const; - void setCountryMode(CountryFrequency_t mode); + CountryModeId_t getCountryMode() const; + void setCountryMode(CountryModeId_t mode); uint32_t getInvBootFrequency() const; @@ -58,4 +64,6 @@ private: uint32_t _inverterTargetFrequency = HOYMILES_CMT_WORK_FREQ; bool cmtSwitchDtuFreq(const uint32_t to_frequency); + + CountryModeId_t _countryMode; }; diff --git a/lib/Hoymiles/src/commands/ChannelChangeCommand.cpp b/lib/Hoymiles/src/commands/ChannelChangeCommand.cpp index 3681ca2..3017850 100644 --- a/lib/Hoymiles/src/commands/ChannelChangeCommand.cpp +++ b/lib/Hoymiles/src/commands/ChannelChangeCommand.cpp @@ -26,7 +26,7 @@ ChannelChangeCommand::ChannelChangeCommand(const uint64_t target_address, const _payload[13] = 0x14; _payload_size = 14; - setCountryMode(CountryFrequency_t::MODE_860); + setCountryMode(CountryModeId_t::MODE_EU); setChannel(channel); setTimeout(10); } @@ -46,10 +46,15 @@ uint8_t ChannelChangeCommand::getChannel() const return _payload[12]; } -void ChannelChangeCommand::setCountryMode(const CountryFrequency_t mode) +void ChannelChangeCommand::setCountryMode(const CountryModeId_t mode) { switch (mode) { - case CountryFrequency_t::MODE_900: + case CountryModeId_t::MODE_US: + _payload[9] = 0x03; + _payload[10] = 0x17; + _payload[11] = 0x3c; + break; + case CountryModeId_t::MODE_BR: _payload[9] = 0x03; _payload[10] = 0x17; _payload[11] = 0x3c; diff --git a/lib/Hoymiles/src/commands/ChannelChangeCommand.h b/lib/Hoymiles/src/commands/ChannelChangeCommand.h index 126215e..44a4c9e 100644 --- a/lib/Hoymiles/src/commands/ChannelChangeCommand.h +++ b/lib/Hoymiles/src/commands/ChannelChangeCommand.h @@ -2,7 +2,7 @@ #pragma once #include "CommandAbstract.h" -#include +#include "../HoymilesRadio_CMT.h" class ChannelChangeCommand : public CommandAbstract { public: @@ -13,7 +13,7 @@ public: void setChannel(const uint8_t channel); uint8_t getChannel() const; - void setCountryMode(const CountryFrequency_t mode); + void setCountryMode(const CountryModeId_t mode); virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);