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()
{
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);

View File

@ -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;
};

View File

@ -6,6 +6,27 @@
#include "Hoymiles.h"
#include "crc.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
{
@ -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<uint32_t>(countryDefinition.at(_countryMode).Freq_Legal_Min / 1e6),
static_cast<uint32_t>(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()

View File

@ -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;
};

View File

@ -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;

View File

@ -2,7 +2,7 @@
#pragma once
#include "CommandAbstract.h"
#include <cmt2300wrapper.h>
#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);