Added frequency and command definitions for the 900 MHz band (North America)

This commit is contained in:
Thomas Basler 2024-01-13 15:29:17 +01:00
parent 16cd1a90d5
commit 6b44694a12
9 changed files with 321 additions and 18 deletions

View File

@ -0,0 +1,216 @@
/*
;---------------------------------------
; CMT2300A Configuration File
; Generated by CMOSTEK RFPDK 1.46
; 2023.03.17 23:16
;---------------------------------------
; Mode = Advanced
; Part Number = CMT2300A
; Frequency = 900.000 MHz
; Xtal Frequency = 26.0000 MHz
; Demodulation = GFSK
; AGC = On
; Data Rate = 20.0 kbps
; Deviation = 20.0 kHz
; Tx Xtal Tol. = 20 ppm
; Rx Xtal Tol. = 20 ppm
; TRx Matching Network Type = 20 dBm
; Tx Power = +13 dBm
; Gaussian BT = 0.5
; Bandwidth = Auto-Select kHz
; CDR Type = Counting
; CDR DR Range = NA
; AFC = On
; AFC Method = Auto-Select
; Data Representation = 0:F-low 1:F-high
; Rx Duty-Cycle = Off
; Tx Duty-Cycle = Off
; Sleep Timer = Off
; Sleep Time = NA
; Rx Timer = Off
; Rx Time T1 = NA
; Rx Time T2 = NA
; Rx Exit State = STBY
; Tx Exit State = STBY
; SLP Mode = Disable
; RSSI Valid Source = PJD
; PJD Window = 8 Jumps
; LFOSC Calibration = On
; Xtal Stable Time = 155 us
; RSSI Compare TH = NA
; Data Mode = Packet
; Whitening = Disable
; Whiten Type = NA
; Whiten Seed Type = NA
; Whiten Seed = NA
; Manchester = Disable
; Manchester Type = NA
; FEC = Enable
; FEC Type = x^3+x^2+1
; Tx Prefix Type = 0
; Tx Packet Number = 1
; Tx Packet Gap = 32
; Packet Type = Variable Length
; Node-Length Position = First Node, then Length
; Payload Bit Order = Start from msb
; Preamble Rx Size = 2
; Preamble Tx Size = 30
; Preamble Value = 170
; Preamble Unit = 8-bit
; Sync Size = 4-byte
; Sync Value = 1296587336
; Sync Tolerance = None
; Sync Manchester = Disable
; Node ID Size = NA
; Node ID Value = NA
; Node ID Mode = None
; Node ID Err Mask = Disable
; Node ID Free = Disable
; Payload Length = 32
; CRC Options = IBM-16
; CRC Seed = 0 crc_seed
; CRC Range = Entire Payload
; CRC Swap = Start from MSB
; CRC Bit Invert = Normal
; CRC Bit Order = Start from bit 15
; Dout Mute = Off
; Dout Adjust Mode = Disable
; Dout Adjust Percentage = NA
; Collision Detect = Off
; Collision Detect Offset = NA
; RSSI Detect Mode = At PREAM_OK
; RSSI Filter Setting = 32-tap
; RF Performance = High
; LBD Threshold = 2.4 V
; RSSI Offset = 0
; RSSI Offset Sign = 0
*/
#ifndef __CMT2300A_PARAMS_900_H
#define __CMT2300A_PARAMS_900_H
#include "cmt2300a_defs.h"
#include <stdint.h>
#define CMT_BASE_FREQ_900 900000000
/* [CMT Bank] with RSSI offset of +- 0 (and Tx power double bit not set) */
static uint8_t g_cmt2300aCmtBank_900[CMT2300A_CMT_BANK_SIZE] = {
0x00,
0x66,
0xEC,
0x1C,
0x70,
0x80,
0x14,
0x08,
0x11,
0x02,
0x02,
0x00,
};
/* [System Bank] */
static uint8_t g_cmt2300aSystemBank_900[CMT2300A_SYSTEM_BANK_SIZE] = {
0xAE,
0xE0,
0x35,
0x00,
0x00,
0xF4,
0x10,
0xE2,
0x42,
0x20,
0x0C,
0x81,
};
/* [Frequency Bank] 900 MHz */
static uint8_t g_cmt2300aFrequencyBank_900[CMT2300A_FREQUENCY_BANK_SIZE] = {
0x45,
0x46,
0x0A,
0x84,
0x45,
0x3B,
0xB1,
0x13,
};
/* [Data Rate Bank] */
static uint8_t g_cmt2300aDataRateBank_900[CMT2300A_DATA_RATE_BANK_SIZE] = {
0xA6,
0xC9,
0x20,
0x20,
0xD2,
0x35,
0x0C,
0x0B,
0x9F,
0x4B,
0x29,
0x29,
0xC0,
0x14,
0x05,
0x53,
0x10,
0x00,
0xB4,
0x00,
0x00,
0x01,
0x00,
0x00,
};
/* [Baseband Bank] - EU */
static uint8_t g_cmt2300aBasebandBank_900[CMT2300A_BASEBAND_BANK_SIZE] = {
0x12,
0x1E,
0x00,
0xAA,
0x06,
0x00,
0x00,
0x00,
0x00,
0x48,
0x5A,
0x48,
0x4D,
0x01,
0x1F,
0x00,
0x00,
0x00,
0x00,
0x00,
0xC3,
0x00,
0x00,
0x60,
0xFF,
0x00,
0x00,
0x1F,
0x10,
};
/* [Tx Bank] 13 dBm */
static uint8_t g_cmt2300aTxBank_900[CMT2300A_TX_BANK_SIZE] = {
0x70,
0x4D,
0x06,
0x00,
0x07,
0x50,
0x00,
0x53,
0x09,
0x3F,
0x7F,
};
#endif

View File

@ -5,6 +5,7 @@
#include "cmt2300wrapper.h" #include "cmt2300wrapper.h"
#include "cmt2300a.h" #include "cmt2300a.h"
#include "cmt2300a_params_860.h" #include "cmt2300a_params_860.h"
#include "cmt2300a_params_900.h"
CMT2300A::CMT2300A(uint8_t pin_sdio, uint8_t pin_clk, uint8_t pin_cs, uint8_t pin_fcs, uint32_t spi_speed) CMT2300A::CMT2300A(uint8_t pin_sdio, uint8_t pin_clk, uint8_t pin_cs, uint8_t pin_fcs, uint32_t spi_speed)
{ {
@ -244,7 +245,25 @@ bool CMT2300A::rxFifoAvailable()
uint32_t CMT2300A::getBaseFrequency() uint32_t CMT2300A::getBaseFrequency()
{ {
return CMT_BASE_FREQ_860; // from Frequency Bank in cmt2300a_params.h switch (_countryMode) {
case CountryFrequency_t::MODE_900:
return CMT_BASE_FREQ_900;
break;
default:
return CMT_BASE_FREQ_860;
break;
}
}
CountryFrequency_t CMT2300A::getCountryMode() const
{
return _countryMode;
}
void CMT2300A::setCountryMode(const CountryFrequency_t mode)
{
_countryMode = mode;
_init_radio();
} }
void CMT2300A::flush_rx(void) void CMT2300A::flush_rx(void)
@ -266,12 +285,24 @@ bool CMT2300A::_init_radio()
} }
/* config registers */ /* config registers */
CMT2300A_ConfigRegBank(CMT2300A_CMT_BANK_ADDR, g_cmt2300aCmtBank_860, CMT2300A_CMT_BANK_SIZE); switch (_countryMode) {
CMT2300A_ConfigRegBank(CMT2300A_SYSTEM_BANK_ADDR, g_cmt2300aSystemBank_860, CMT2300A_SYSTEM_BANK_SIZE); case CountryFrequency_t::MODE_900:
CMT2300A_ConfigRegBank(CMT2300A_FREQUENCY_BANK_ADDR, g_cmt2300aFrequencyBank_860, CMT2300A_FREQUENCY_BANK_SIZE); CMT2300A_ConfigRegBank(CMT2300A_CMT_BANK_ADDR, g_cmt2300aCmtBank_900, CMT2300A_CMT_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_DATA_RATE_BANK_ADDR, g_cmt2300aDataRateBank_860, CMT2300A_DATA_RATE_BANK_SIZE); CMT2300A_ConfigRegBank(CMT2300A_SYSTEM_BANK_ADDR, g_cmt2300aSystemBank_900, CMT2300A_SYSTEM_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_BASEBAND_BANK_ADDR, g_cmt2300aBasebandBank_860, CMT2300A_BASEBAND_BANK_SIZE); CMT2300A_ConfigRegBank(CMT2300A_FREQUENCY_BANK_ADDR, g_cmt2300aFrequencyBank_900, CMT2300A_FREQUENCY_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_TX_BANK_ADDR, g_cmt2300aTxBank_860, CMT2300A_TX_BANK_SIZE); CMT2300A_ConfigRegBank(CMT2300A_DATA_RATE_BANK_ADDR, g_cmt2300aDataRateBank_900, CMT2300A_DATA_RATE_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_BASEBAND_BANK_ADDR, g_cmt2300aBasebandBank_900, CMT2300A_BASEBAND_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_TX_BANK_ADDR, g_cmt2300aTxBank_900, CMT2300A_TX_BANK_SIZE);
break;
default:
CMT2300A_ConfigRegBank(CMT2300A_CMT_BANK_ADDR, g_cmt2300aCmtBank_860, CMT2300A_CMT_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_SYSTEM_BANK_ADDR, g_cmt2300aSystemBank_860, CMT2300A_SYSTEM_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_FREQUENCY_BANK_ADDR, g_cmt2300aFrequencyBank_860, CMT2300A_FREQUENCY_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_DATA_RATE_BANK_ADDR, g_cmt2300aDataRateBank_860, CMT2300A_DATA_RATE_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_BASEBAND_BANK_ADDR, g_cmt2300aBasebandBank_860, CMT2300A_BASEBAND_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_TX_BANK_ADDR, g_cmt2300aTxBank_860, CMT2300A_TX_BANK_SIZE);
break;
}
// xosc_aac_code[2:0] = 2 // xosc_aac_code[2:0] = 2
uint8_t tmp; uint8_t tmp;

View File

@ -7,6 +7,12 @@
#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 {
MODE_860,
MODE_900,
CountryFrequency_Max,
};
class CMT2300A { class CMT2300A {
public: public:
CMT2300A(uint8_t pin_sdio, uint8_t pin_clk, uint8_t pin_cs, uint8_t pin_fcs, uint32_t _spi_speed = CMT_SPI_SPEED); CMT2300A(uint8_t pin_sdio, uint8_t pin_clk, uint8_t pin_cs, uint8_t pin_fcs, uint32_t _spi_speed = CMT_SPI_SPEED);
@ -87,6 +93,9 @@ public:
uint32_t getBaseFrequency(); uint32_t getBaseFrequency();
CountryFrequency_t getCountryMode() const;
void setCountryMode(const CountryFrequency_t mode);
/** /**
* Empty the RX (receive) FIFO buffers. * Empty the RX (receive) FIFO buffers.
*/ */
@ -110,4 +119,6 @@ private:
int8_t _pin_cs; int8_t _pin_cs;
int8_t _pin_fcs; int8_t _pin_fcs;
uint32_t _spi_speed; uint32_t _spi_speed;
CountryFrequency_t _countryMode = CountryFrequency_t::MODE_860;
}; };

View File

@ -23,10 +23,14 @@ 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 (frequency < 863000000 || frequency > 870000000) { 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", Hoymiles.getMessageOutput()->printf("!!! caution: %.2f MHz is out of EU legal range! (863 - 870 MHz)\r\n",
frequency / 1000000.0); 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);
}
return (frequency - _radio->getBaseFrequency()) / getChannelWidth(); // frequency to channel return (frequency - _radio->getBaseFrequency()) / getChannelWidth(); // frequency to channel
} }
@ -197,10 +201,28 @@ uint32_t HoymilesRadio_CMT::getChannelWidth()
return FH_OFFSET * CMT2300A_ONE_STEP_SIZE; return FH_OFFSET * CMT2300A_ONE_STEP_SIZE;
} }
uint32_t HoymilesRadio_CMT::getInvBootFrequency() CountryFrequency_t HoymilesRadio_CMT::getCountryMode() const
{
return _radio->getCountryMode();
}
void HoymilesRadio_CMT::setCountryMode(CountryFrequency_t mode)
{
_radio->setCountryMode(mode);
}
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 868000000;
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

@ -30,7 +30,10 @@ public:
uint32_t getMaxFrequency() const; uint32_t getMaxFrequency() const;
static uint32_t getChannelWidth(); static uint32_t getChannelWidth();
static uint32_t getInvBootFrequency(); CountryFrequency_t getCountryMode() const;
void setCountryMode(CountryFrequency_t mode);
uint32_t getInvBootFrequency() const;
uint32_t getFrequencyFromChannel(const uint8_t channel) const; uint32_t getFrequencyFromChannel(const uint8_t channel) const;
uint8_t getChannelFromFrequency(const uint32_t frequency) const; uint8_t getChannelFromFrequency(const uint32_t frequency) const;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
/* /*
* Copyright (C) 2023 Thomas Basler and others * Copyright (C) 2023-2024 Thomas Basler and others
*/ */
/* /*
@ -12,7 +12,8 @@ Command structure:
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
----------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------
56 71 60 35 46 80 12 23 04 02 15 21 00 14 00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 56 71 60 35 46 80 12 23 04 02 15 21 00 14 00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- (860 MHz band)
56 71 60 35 46 80 12 23 04 03 17 3c 00 14 00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- (900 MHz band)
^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^
ID Target Addr Source Addr ? ? ? CH ? CRC8 ID Target Addr Source Addr ? ? ? CH ? CRC8
*/ */
@ -22,12 +23,10 @@ ChannelChangeCommand::ChannelChangeCommand(const uint64_t target_address, const
: CommandAbstract(target_address, router_address) : CommandAbstract(target_address, router_address)
{ {
_payload[0] = 0x56; _payload[0] = 0x56;
_payload[9] = 0x02;
_payload[10] = 0x15;
_payload[11] = 0x21;
_payload[13] = 0x14; _payload[13] = 0x14;
_payload_size = 14; _payload_size = 14;
setCountryMode(CountryFrequency_t::MODE_860);
setChannel(channel); setChannel(channel);
setTimeout(10); setTimeout(10);
} }
@ -47,6 +46,22 @@ uint8_t ChannelChangeCommand::getChannel() const
return _payload[12]; return _payload[12];
} }
void ChannelChangeCommand::setCountryMode(const CountryFrequency_t mode)
{
switch (mode) {
case CountryFrequency_t::MODE_900:
_payload[9] = 0x03;
_payload[10] = 0x17;
_payload[11] = 0x3c;
break;
default:
_payload[9] = 0x02;
_payload[10] = 0x15;
_payload[11] = 0x21;
break;
}
}
bool ChannelChangeCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id) bool ChannelChangeCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
{ {
return true; return true;

View File

@ -2,6 +2,7 @@
#pragma once #pragma once
#include "CommandAbstract.h" #include "CommandAbstract.h"
#include <cmt2300wrapper.h>
class ChannelChangeCommand : public CommandAbstract { class ChannelChangeCommand : public CommandAbstract {
public: public:
@ -12,6 +13,8 @@ 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);
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);
virtual uint8_t getMaxResendCount(); virtual uint8_t getMaxResendCount();

View File

@ -19,6 +19,7 @@ bool HMS_Abstract::sendChangeChannelRequest()
} }
auto cmdChannel = _radio->prepareCommand<ChannelChangeCommand>(); auto cmdChannel = _radio->prepareCommand<ChannelChangeCommand>();
cmdChannel->setCountryMode(Hoymiles.getRadioCmt()->getCountryMode());
cmdChannel->setChannel(Hoymiles.getRadioCmt()->getChannelFromFrequency(Hoymiles.getRadioCmt()->getInverterTargetFrequency())); cmdChannel->setChannel(Hoymiles.getRadioCmt()->getChannelFromFrequency(Hoymiles.getRadioCmt()->getInverterTargetFrequency()));
cmdChannel->setTargetAddress(serial()); cmdChannel->setTargetAddress(serial());
_radio->enqueCommand(cmdChannel); _radio->enqueCommand(cmdChannel);

View File

@ -21,6 +21,7 @@ bool HMT_Abstract::sendChangeChannelRequest()
} }
auto cmdChannel = _radio->prepareCommand<ChannelChangeCommand>(); auto cmdChannel = _radio->prepareCommand<ChannelChangeCommand>();
cmdChannel->setCountryMode(Hoymiles.getRadioCmt()->getCountryMode());
cmdChannel->setChannel(Hoymiles.getRadioCmt()->getChannelFromFrequency(Hoymiles.getRadioCmt()->getInverterTargetFrequency())); cmdChannel->setChannel(Hoymiles.getRadioCmt()->getChannelFromFrequency(Hoymiles.getRadioCmt()->getInverterTargetFrequency()));
cmdChannel->setTargetAddress(serial()); cmdChannel->setTargetAddress(serial());
_radio->enqueCommand(cmdChannel); _radio->enqueCommand(cmdChannel);