File: gd73_interface.cc

package info (click to toggle)
qdmr 0.13.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 22,420 kB
  • sloc: cpp: 95,929; xml: 10,749; python: 1,108; makefile: 78; sh: 9
file content (126 lines) | stat: -rw-r--r-- 3,410 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
115
116
117
118
119
120
121
122
123
124
125
126
#include "gd73_interface.hh"
#include "logger.hh"
#include <QtEndian>

#define BLOCK_SIZE 0x35

GD73Interface::GD73Interface(const USBDeviceDescriptor &descriptor, const ErrorStack &err, QObject *parent)
  : C7000Device(descriptor, err, parent), RadioInterface()
{
  Packet request, response;
  if (nullptr == _dev) {
    errMsg(err) << "Cannot initialize GD73 interface: C7000 interface not open.";
    return;
  }

  request = Packet(0x01, 0x04);
  if (! sendRecv(request, response, err)) {
    errMsg(err) << "Cannot enter programming mode.";
    C7000Device::close();
  }
  logDebug() << "Entered prog mode. Response: " << response.payload().toHex() << ".";
}

bool
GD73Interface::isOpen() const {
  return C7000Device::isOpen();
}

RadioInfo
GD73Interface::identifier(const ErrorStack &err) {
  Q_UNUSED(err);
  return RadioInfo::byID(RadioInfo::GD73);
}

void
GD73Interface::close() {
  C7000Device::close();
}

bool
GD73Interface::write_start(uint32_t bank, uint32_t addr, const ErrorStack &err) {
  Q_UNUSED(bank); Q_UNUSED(addr); Q_UNUSED(err);
  return true;
}

bool
GD73Interface::write(uint32_t bank, uint32_t addr, uint8_t *data, int nbytes, const ErrorStack &err) {
  Q_UNUSED(bank);

  if ((addr%BLOCK_SIZE) || (nbytes!=BLOCK_SIZE)) {
    errMsg(err) << "Address and size must align with block size of 35h";
    return false;
  }

  C7000Device::Packet request, response;
  QByteArray payload; payload.resize(2);
  *((uint16_t *)payload.data()) = qToLittleEndian((uint16_t)(addr/BLOCK_SIZE));
  payload.append((char *)data, nbytes);
  request = C7000Device::Packet(0x01, 0x00, 0x0f, payload);
  if (! sendRecv(request, response, err)) {
    errMsg(err) << "Cannot send write command.";
    return false;
  }

  return true;
}

bool
GD73Interface::write_finish(const ErrorStack &err) {
  Q_UNUSED(err);
  return true;
}

bool
GD73Interface::read_start(uint32_t bank, uint32_t addr, const ErrorStack &err) {
  Q_UNUSED(bank); Q_UNUSED(addr); Q_UNUSED(err);
  _lastSequence = 0xffff;
  logDebug() << "Start codeplug read, seqnr=" << Qt::hex << _lastSequence << "h.";
  return true;
}

bool
GD73Interface::read(uint32_t bank, uint32_t addr, uint8_t *data, int nbytes, const ErrorStack &err) {
  Q_UNUSED(bank);

  if ((addr%BLOCK_SIZE) || (nbytes!=BLOCK_SIZE)) {
    errMsg(err) << "Address and size must align with block size of 35h";
    return false;
  }

  //logDebug() << "Read " << nbytes << "bytes from address " << Qt::hex << addr << "h.";

  uint16_t seqNum = addr/BLOCK_SIZE;
  if (uint16_t(_lastSequence+1) != seqNum) {
    errMsg(err) << "Out-of-sequence read: Expected seqnr. " << uint16_t(_lastSequence+1)
                << " got " << seqNum << ".";
    return false;
  }

  C7000Device::Packet request, response;
  if (0xffff == _lastSequence) {
    // Request start-of-read
    request = C7000Device::Packet(0x01, 0x02);
  } else {
    QByteArray payload(2,0); *((uint16_t *)payload.data()) = qToLittleEndian(_lastSequence);
    request = C7000Device::Packet(0x04, 0x01, 0x0f, payload);
  }

  if (! sendRecv(request, response, err)) {
    errMsg(err) << "Cannot read codeplug from device.";
    return false;
  }

  _lastSequence = qFromLittleEndian(*(uint16_t *)response.payload().data());
  memcpy(data, response.payload().data()+2, nbytes);

  return true;
}

bool
GD73Interface::read_finish(const ErrorStack &err) {
  Q_UNUSED(err);
  _lastSequence = 0xffff;
  return true;
}