File: md390.cc

package info (click to toggle)
qdmr 0.13.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 22,236 kB
  • sloc: cpp: 93,672; xml: 10,526; python: 1,108; makefile: 78; sh: 10
file content (114 lines) | stat: -rw-r--r-- 3,820 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "md390.hh"
#include "md390_limits.hh"

#include "logger.hh"
#include "utils.hh"

#define NUM_CHANNELS                1000
#define ADDR_CHANNELS           0x01ee00
#define CHANNEL_SIZE            0x000040
#define BLOCK_SIZE                  1024


MD390::MD390(TyTInterface *device, const ErrorStack &err, QObject *parent)
  : TyTRadio(device, parent), _name("TyT MD-390"), _limits(nullptr)
{
  // Read channels and identify device variance based on the channel frequencies. This may block
  // the GUI for some time.
  unsigned addr_start = align_addr(ADDR_CHANNELS, BLOCK_SIZE);
  unsigned channel_offset = ADDR_CHANNELS-addr_start;
  uint total_size = align_size(addr_start+NUM_CHANNELS*CHANNEL_SIZE, BLOCK_SIZE)-addr_start;
  QByteArray buffer(total_size, 0xff);

  if (! _dev->read_start(0, addr_start, err)) {
    errMsg(err) << "Cannot read channels from MD-390, cannot determine variant.";
    return;
  }
  for (unsigned i=0; i<(total_size/BLOCK_SIZE); i++){
    if (! _dev->read(0, ADDR_CHANNELS, (uint8_t *)buffer.data()+i*BLOCK_SIZE, BLOCK_SIZE, err)) {
      errMsg(err) << "Cannot read channels from MD-390, cannot determine variant.";
      return;
    }
  }
  _dev->read_finish(err);

  // Determine frequency range of channels
  unsigned channelCount = 0;
  QPair<double, double> range(std::numeric_limits<double>::max(),0);
  for (unsigned i=0; i<NUM_CHANNELS; i++) {
    MD390Codeplug::ChannelElement channel(
          ((uint8_t *)buffer.data()) + channel_offset + i*CHANNEL_SIZE);
    if (! channel.isValid())
      continue;
    if (channel.rxFrequency().inHz()) {
      range.first = std::min(range.first, channel.rxFrequency().inMHz());
      range.second = std::max(range.second, channel.rxFrequency().inMHz());
    }
    if (channel.txFrequency().inHz()) {
      range.first = std::min(range.first, channel.txFrequency().inMHz());
      range.second = std::max(range.second, channel.txFrequency().inMHz());
    }
    channelCount++;
  }

  logDebug() << "Got frequency range " << range.first << "MHz - " << range.second
             << "MHz from " << channelCount << " channels.";

  if ((137<=range.first) && (174>=range.second)) {
    _limits = new MD390Limits({{Frequency::fromMHz(136.), Frequency::fromMHz(174.)}}, this);
    _name += "V";
  } else if ((350<=range.first) && (400>=range.second)) {
    _limits = new MD390Limits({{Frequency::fromMHz(350.), Frequency::fromMHz(400.)}}, this);
    _name += "U";
  } else if ((400<=range.first) && (450>=range.second)) {
    _limits = new MD390Limits({{Frequency::fromMHz(400.), Frequency::fromMHz(480.)}}, this);
    _name += "U";
  } else if ((450<=range.first) && (520>=range.second)) {
    _limits = new MD390Limits({{Frequency::fromMHz(450.), Frequency::fromMHz(520.)}}, this);
    _name += "U";
  } else {
    // Invalid frequency range, needs "Ignore frequency limits" in settings to write any codeplug.
    _limits = new MD390Limits({}, this);
    errMsg(err) << "Cannot determine frequency range from channel frequencies between "
                << range.first << "MHz and " << range.second
                << "MHz. Will not check frequency ranges.";
  }
}

const QString &
MD390::name() const {
  return _name;
}

const RadioLimits &
MD390::limits() const {
  return *_limits;
}

const Codeplug &
MD390::codeplug() const {
  return _codeplug;
}

Codeplug &
MD390::codeplug() {
  return _codeplug;
}

const CallsignDB *
MD390::callsignDB() const {
  return nullptr;
}

CallsignDB *
MD390::callsignDB() {
  return nullptr;
}

RadioInfo
MD390::defaultRadioInfo() {
  return RadioInfo(RadioInfo::MD390, "md390", "MD-390", "TyT", {TyTInterface::interfaceInfo()},
                   QList<RadioInfo>{
                     RadioInfo(RadioInfo::RT8, "rt8", "RT8", "Retevis", {TyTInterface::interfaceInfo()})
                   });
}