Distinct between Band and Country

This allows different frequencies (Startup/Default etc.) for the same band configuration.
This commit is contained in:
Thomas Basler 2024-01-14 00:06:35 +01:00
parent 6b44694a12
commit 188c4688ab
6 changed files with 69 additions and 42 deletions

View File

@ -245,8 +245,8 @@ bool CMT2300A::rxFifoAvailable()
uint32_t CMT2300A::getBaseFrequency() uint32_t CMT2300A::getBaseFrequency()
{ {
switch (_countryMode) { switch (_frequencyBand) {
case CountryFrequency_t::MODE_900: case FrequencyBand_t::BAND_900:
return CMT_BASE_FREQ_900; return CMT_BASE_FREQ_900;
break; break;
default: 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(); _init_radio();
} }
@ -285,8 +285,8 @@ bool CMT2300A::_init_radio()
} }
/* config registers */ /* config registers */
switch (_countryMode) { switch (_frequencyBand) {
case CountryFrequency_t::MODE_900: case FrequencyBand_t::BAND_900:
CMT2300A_ConfigRegBank(CMT2300A_CMT_BANK_ADDR, g_cmt2300aCmtBank_900, CMT2300A_CMT_BANK_SIZE); 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_SYSTEM_BANK_ADDR, g_cmt2300aSystemBank_900, CMT2300A_SYSTEM_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_FREQUENCY_BANK_ADDR, g_cmt2300aFrequencyBank_900, CMT2300A_FREQUENCY_BANK_SIZE); CMT2300A_ConfigRegBank(CMT2300A_FREQUENCY_BANK_ADDR, g_cmt2300aFrequencyBank_900, CMT2300A_FREQUENCY_BANK_SIZE);

View File

@ -7,10 +7,10 @@
#define FH_OFFSET 100 // value * CMT2300A_ONE_STEP_SIZE = channel frequency offset #define FH_OFFSET 100 // value * CMT2300A_ONE_STEP_SIZE = channel frequency offset
#define CMT_SPI_SPEED 4000000 // 4 MHz #define CMT_SPI_SPEED 4000000 // 4 MHz
enum CountryFrequency_t { enum FrequencyBand_t {
MODE_860, BAND_860,
MODE_900, BAND_900,
CountryFrequency_Max, FrequencyBand_Max,
}; };
class CMT2300A { class CMT2300A {
@ -93,8 +93,8 @@ public:
uint32_t getBaseFrequency(); uint32_t getBaseFrequency();
CountryFrequency_t getCountryMode() const; FrequencyBand_t getFrequencyBand() const;
void setCountryMode(const CountryFrequency_t mode); void setFrequencyBand(const FrequencyBand_t mode);
/** /**
* Empty the RX (receive) FIFO buffers. * Empty the RX (receive) FIFO buffers.
@ -120,5 +120,5 @@ private:
int8_t _pin_fcs; int8_t _pin_fcs;
uint32_t _spi_speed; uint32_t _spi_speed;
CountryFrequency_t _countryMode = CountryFrequency_t::MODE_860; FrequencyBand_t _frequencyBand = FrequencyBand_t::BAND_860;
}; };

View File

@ -6,6 +6,27 @@
#include "Hoymiles.h" #include "Hoymiles.h"
#include "crc.h" #include "crc.h"
#include <FunctionalInterrupt.h> #include <FunctionalInterrupt.h>
#include <frozen/map.h>
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<CountryModeId_t, CountryFrequencyDefinition_t, 3> 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 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); frequency / 1000000.0, getMinFrequency() / 1000000.0, getMaxFrequency() / 1000000.0);
return 0xFF; // ERROR return 0xFF; // ERROR
} }
if (_radio->getCountryMode() == CountryFrequency_t::MODE_860 && (frequency < 863000000 || frequency > 870000000)) { if (frequency < countryDefinition.at(_countryMode).Freq_Legal_Min || frequency > countryDefinition.at(_countryMode).Freq_Legal_Max) {
Hoymiles.getMessageOutput()->printf("!!! caution: %.2f MHz is out of EU legal range! (863 - 870 MHz)\r\n", Hoymiles.getMessageOutput()->printf("!!! caution: %.2f MHz is out of region legal range! (%d - %d MHz)\r\n",
frequency / 1000000.0); frequency / 1000000.0,
} static_cast<uint32_t>(countryDefinition.at(_countryMode).Freq_Legal_Min / 1e6),
if (_radio->getCountryMode() == CountryFrequency_t::MODE_900 && (frequency < 902000000 || frequency > 928000000)) { static_cast<uint32_t>(countryDefinition.at(_countryMode).Freq_Legal_Max / 1e6));
Hoymiles.getMessageOutput()->printf("!!! caution: %.2f MHz is out of North America legal range! (902 - 928 MHz)\r\n",
frequency / 1000000.0);
} }
return (frequency - _radio->getBaseFrequency()) / getChannelWidth(); // frequency to channel 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(); _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 cmtSwitchDtuFreq(_inverterTargetFrequency); // start dtu at work freqency, for fast Rx if inverter is already on and frequency switched
if (!_radio->isChipConnected()) { if (!_radio->isChipConnected()) {
@ -201,28 +222,21 @@ uint32_t HoymilesRadio_CMT::getChannelWidth()
return FH_OFFSET * CMT2300A_ONE_STEP_SIZE; 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 uint32_t HoymilesRadio_CMT::getInvBootFrequency() const
{ {
// Hoymiles boot/init frequency after power up inverter or connection lost for 15 min // Hoymiles boot/init frequency after power up inverter or connection lost for 15 min
return countryDefinition.at(_countryMode).Freq_StartUp;
switch(_radio->getCountryMode()) {
case CountryFrequency_t::MODE_900:
return 915000000;
break;
default:
return 868000000;
break;
}
} }
void ARDUINO_ISR_ATTR HoymilesRadio_CMT::handleInt1() void ARDUINO_ISR_ATTR HoymilesRadio_CMT::handleInt1()

View File

@ -16,6 +16,12 @@
#define HOYMILES_CMT_WORK_FREQ 865000000 #define HOYMILES_CMT_WORK_FREQ 865000000
#endif #endif
enum CountryModeId_t {
MODE_EU,
MODE_US,
MODE_BR,
};
class HoymilesRadio_CMT : public HoymilesRadio { class HoymilesRadio_CMT : public HoymilesRadio {
public: 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); 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; uint32_t getMaxFrequency() const;
static uint32_t getChannelWidth(); static uint32_t getChannelWidth();
CountryFrequency_t getCountryMode() const; CountryModeId_t getCountryMode() const;
void setCountryMode(CountryFrequency_t mode); void setCountryMode(CountryModeId_t mode);
uint32_t getInvBootFrequency() const; uint32_t getInvBootFrequency() const;
@ -58,4 +64,6 @@ private:
uint32_t _inverterTargetFrequency = HOYMILES_CMT_WORK_FREQ; uint32_t _inverterTargetFrequency = HOYMILES_CMT_WORK_FREQ;
bool cmtSwitchDtuFreq(const uint32_t to_frequency); bool cmtSwitchDtuFreq(const uint32_t to_frequency);
CountryModeId_t _countryMode;
}; };

View File

@ -26,7 +26,7 @@ ChannelChangeCommand::ChannelChangeCommand(const uint64_t target_address, const
_payload[13] = 0x14; _payload[13] = 0x14;
_payload_size = 14; _payload_size = 14;
setCountryMode(CountryFrequency_t::MODE_860); setCountryMode(CountryModeId_t::MODE_EU);
setChannel(channel); setChannel(channel);
setTimeout(10); setTimeout(10);
} }
@ -46,10 +46,15 @@ uint8_t ChannelChangeCommand::getChannel() const
return _payload[12]; return _payload[12];
} }
void ChannelChangeCommand::setCountryMode(const CountryFrequency_t mode) void ChannelChangeCommand::setCountryMode(const CountryModeId_t mode)
{ {
switch (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[9] = 0x03;
_payload[10] = 0x17; _payload[10] = 0x17;
_payload[11] = 0x3c; _payload[11] = 0x3c;

View File

@ -2,7 +2,7 @@
#pragma once #pragma once
#include "CommandAbstract.h" #include "CommandAbstract.h"
#include <cmt2300wrapper.h> #include "../HoymilesRadio_CMT.h"
class ChannelChangeCommand : public CommandAbstract { class ChannelChangeCommand : public CommandAbstract {
public: public:
@ -13,7 +13,7 @@ public:
void setChannel(const uint8_t channel); void setChannel(const uint8_t channel);
uint8_t getChannel() const; 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); virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);