|  | 
| 7 | 7 | #include "crc.h" | 
| 8 | 8 | #include <FunctionalInterrupt.h> | 
| 9 | 9 | #include <frozen/map.h> | 
|  | 10 | +#include "frequencymanagers/FrequencyManagerAbstract.h" | 
| 10 | 11 | 
 | 
| 11 | 12 | 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) | 
| 12 | 13 | { | 
| @@ -192,6 +193,7 @@ void HoymilesRadio_CMT::setPALevel(const int8_t paLevel) | 
| 192 | 193 |     if (!_isInitialized) { | 
| 193 | 194 |         return; | 
| 194 | 195 |     } | 
|  | 196 | +    this->_pa_level = paLevel; | 
| 195 | 197 | 
 | 
| 196 | 198 |     if (_radio->setPALevel(paLevel)) { | 
| 197 | 199 |         Hoymiles.getMessageOutput()->printf("CMT TX power set to %" PRId8 " dBm\r\n", paLevel); | 
| @@ -232,6 +234,16 @@ uint32_t HoymilesRadio_CMT::getMaxFrequency() const | 
| 232 | 234 |     return countryDefinition.at(_countryMode).Freq_Max; | 
| 233 | 235 | } | 
| 234 | 236 | 
 | 
|  | 237 | +uint32_t HoymilesRadio_CMT::getLegalMinFrequency() const | 
|  | 238 | +{ | 
|  | 239 | +    return countryDefinition.at(_countryMode).Freq_Legal_Min; | 
|  | 240 | +} | 
|  | 241 | + | 
|  | 242 | +uint32_t HoymilesRadio_CMT::getLegalMaxFrequency() const | 
|  | 243 | +{ | 
|  | 244 | +    return countryDefinition.at(_countryMode).Freq_Legal_Max; | 
|  | 245 | +} | 
|  | 246 | + | 
| 235 | 247 | CountryModeId_t HoymilesRadio_CMT::getCountryMode() const | 
| 236 | 248 | { | 
| 237 | 249 |     return _countryMode; | 
| @@ -262,26 +274,50 @@ void ARDUINO_ISR_ATTR HoymilesRadio_CMT::handleInt2() | 
| 262 | 274 |     _packetReceived = true; | 
| 263 | 275 | } | 
| 264 | 276 | 
 | 
| 265 |  | -void HoymilesRadio_CMT::sendEsbPacket(CommandAbstract& cmd) | 
|  | 277 | +void HoymilesRadio_CMT::handleTxError(bool is_error) { | 
|  | 278 | +    if(!is_error) { | 
|  | 279 | +        this->_tx_error_counter = 0; | 
|  | 280 | +        return; | 
|  | 281 | +    } | 
|  | 282 | +    this->_tx_error_counter++; | 
|  | 283 | +    if(_tx_error_counter==5 || _tx_error_counter == 10 || _tx_error_counter == 15) { | 
|  | 284 | +        Hoymiles.getMessageOutput()->println("TX recovery: Re-applying PA level"); | 
|  | 285 | +        this->setPALevel(this->_pa_level); | 
|  | 286 | +        return; | 
|  | 287 | +    } | 
|  | 288 | +    if(_tx_error_counter==20 || _tx_error_counter == 25) { | 
|  | 289 | +        Hoymiles.getMessageOutput()->println("TX recovery: Re-initializing radio"); | 
|  | 290 | +        this->_radio->begin(); | 
|  | 291 | +    } | 
|  | 292 | +    if(_tx_error_counter >= 30) { | 
|  | 293 | +        Hoymiles.getMessageOutput()->println("TX recovery: Giving up"); | 
|  | 294 | +        this->_isInitialized = false; | 
|  | 295 | +    } | 
|  | 296 | + | 
|  | 297 | +} | 
|  | 298 | + | 
|  | 299 | +void HoymilesRadio_CMT::sendEsbPacket(CommandAbstract& cmd, FrequencyManagerAbstract &freq_mgr) | 
| 266 | 300 | { | 
| 267 | 301 |     cmd.incrementSendCount(); | 
| 268 | 302 | 
 | 
| 269 | 303 |     cmd.setRouterAddress(DtuSerial().u64); | 
| 270 | 304 | 
 | 
| 271 | 305 |     _radio->stopListening(); | 
| 272 | 306 | 
 | 
| 273 |  | -    if (cmd.getDataPayload()[0] == 0x56) { // @todo(tbnobody) Bad hack to identify ChannelChange Command | 
| 274 |  | -        cmtSwitchDtuFreq(getInvBootFrequency()); | 
| 275 |  | -    } | 
|  | 307 | +    cmtSwitchDtuFreq(freq_mgr.getTXFrequency(cmd)); | 
| 276 | 308 | 
 | 
| 277 | 309 |     Hoymiles.getMessageOutput()->printf("TX %s %.2f MHz --> ", | 
| 278 | 310 |         cmd.getCommandName().c_str(), getFrequencyFromChannel(_radio->getChannel()) / 1000000.0); | 
| 279 | 311 |     cmd.dumpDataPayload(Hoymiles.getMessageOutput()); | 
| 280 | 312 | 
 | 
| 281 |  | -    if (!_radio->write(cmd.getDataPayload(), cmd.getDataSize())) { | 
|  | 313 | +    bool tx_worked = _radio->write(cmd.getDataPayload(), cmd.getDataSize()); | 
|  | 314 | +    if (!tx_worked) { | 
| 282 | 315 |         Hoymiles.getMessageOutput()->println("TX SPI Timeout"); | 
| 283 | 316 |     } | 
| 284 |  | -    cmtSwitchDtuFreq(_inverterTargetFrequency); | 
|  | 317 | +    this->handleTxError(!tx_worked); | 
|  | 318 | + | 
|  | 319 | + | 
|  | 320 | +    cmtSwitchDtuFreq(freq_mgr.getRXFrequency(cmd)); | 
| 285 | 321 |     _radio->startListening(); | 
| 286 | 322 |     _busyFlag = true; | 
| 287 | 323 |     _rxTimeout.set(cmd.getTimeout()); | 
|  | 
0 commit comments