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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
|
#ifndef DM1701_CODEPLUG_HH
#define DM1701_CODEPLUG_HH
#include "tyt_codeplug.hh"
/** Device specific implementation of the codeplug for the Baofeng DM-1701.
*
* The codeplug consists of two segments. The first segment starts at address @c 0x002000 and ends at
* address @c 0x040000. The second segment starts at address @c 0x110000 and ends at @c 0x1a0000. The
* segments must align with @c 0x400 (1024 bytes).
*
* @section dm1701cpl Codeplug structure within radio
* The codeplug structure is reverse engineered almost completely and can be programmed from
* scratch. That is, it is not necessary to update an existing codeplug on the radio.
* <table>
* <tr><th>Start</th> <th>End</th> <th>Size</th> <th>Content</th></tr>
* <tr><th colspan="4">First segment 0x002000-0x040000</th></tr>
* <tr><td>0x002000</td> <td>0x00200c</td> <td>0x0000c</td> <td>Timestamp see @c TyTCodeplug::TimestampElement.</td></tr>
* <tr><td>0x00200c</td> <td>0x002040</td> <td>0x00034</td> <td>Reserved, filled with 0xff. </td></tr>
* <tr><td>0x002040</td> <td>0x0020f0</td> <td>0x000b0</td> <td>General settings see @c DM1701Codeplug::GeneralSettingsElement.</td></tr>
* <tr><td>0x0020f0</td> <td>0x002100</td> <td>0x00010</td> <td>Menu settings, see @c TyTCodeplug::MenuSettingsElement</td></tr>
* <tr><td>0x002100</td> <td>0x002140</td> <td>0x00040</td> <td>Button config, see @c DM1701Codeplug::ButtonSettingsElement.</td></tr>
* <tr><td>0x002140</td> <td>0x002180</td> <td>0x00040</td> <td>Reserved, filled with 0xff.</td></tr>
* <tr><td>0x002180</td> <td>0x0059c0</td> <td>0x03840</td> <td>50 Text messages @ 0x120 bytes each.</td></tr>
* <tr><td>0x0059c0</td> <td>0x005a70</td> <td>0x000b0</td> <td>Privacy keys, see @c TyTCodeplug::EncryptionElement.</td></tr>
* <tr><td>0x005a70</td> <td>0x005a80</td> <td>0x00010</td> <td>Emergency system settings, see @c TyTCodeplug::EmergencySettingsElement.</td></td>
* <tr><td>0x005a80</td> <td>0x005f80</td> <td>0x00500</td> <td>Emergency systems, see @c TyTCodeplug::EmergencySystemElement.</td></td>
* <tr><td>0x005f80</td> <td>0x00ec20</td> <td>0x08ca0</td> <td>Reserved, filled with 0xff.</td></td>
* <tr><td>0x00ec20</td> <td>0x0149e0</td> <td>0x05dc0</td> <td>250 RX Group lists @ 0x60 bytes each, see @c TyTCodeplug::GroupListElement.</td></tr>
* <tr><td>0x0149e0</td> <td>0x018860</td> <td>0x03e80</td> <td>250 Zones @ 0x40 bytes each, see @c TyTCodeplug::ZoneElement.</td></tr>
* <tr><td>0x018860</td> <td>0x01edf0</td> <td>0x06590</td> <td>250 Scanlists @ 0x68 bytes each, see @c TyTCodeplug::ScanListElement.</td></tr>
* <tr><td>0x01edf0</td> <td>0x02ef00</td> <td>0x10110</td> <td>Reserved, filled with @c 0xff. </td></tr>
* <tr><td>0x02ef00</td> <td>0x02ef40</td> <td>0x00040</td> <td>VFO A channel, see @c DM1701Codeplug::VFOChannelElement.</td></tr>
* <tr><td>0x02ef40</td> <td>0x02ef80</td> <td>0x00040</td> <td>VFO B channel, see @c DM1701Codeplug::VFOChannelElement.</td></tr>
* <tr><td>0x02ef80</td> <td>0x031000</td> <td>0x02080</td> <td>Reserved, filled with @c 0xff. </td></tr>
* <tr><td>0x031000</td> <td>0x03eac0</td> <td>0x0dac0</td> <td>250 Zone-extensions @ 0xe0 bytes each, see @c DM1701Codeplug::ZoneExtElement.</td></tr>
* <tr><td>0x03eac0</td> <td>0x03ec40</td> <td>0x00180</td> <td>Reserved, filled with @c 0xff. </td></tr>
* <tr><td>0x03ec40</td> <td>0x03ed40</td> <td>0x00100</td> <td>16 GPS systems @ 0x10 bytes each, see @c TyTCodeplug::GPSSystemElement.</td></tr>
* <tr><td>0x03ed40</td> <td>0x040000</td> <td>0x012c0</td> <td>Reserved, filled with @c 0xff. </td></tr>
* <tr><th colspan="4">Second segment 0x110000-0x1a0000</th></tr>
* <tr><td>0x110000</td> <td>0x13ee00</td> <td>0x2ee00</td> <td>3000 Channels @ 0x40 bytes each, see @c DM1701Codeplug::ChannelElement.</td></tr>
* <tr><td>0x13ee00</td> <td>0x140000</td> <td>0x01200</td> <td>Reserved, filled with @c 0xff. </td></tr>
* <tr><td>0x140000</td> <td>0x197e40</td> <td>0x57e40</td> <td>10000 Contacts @ 0x24 bytes each, see @c TyTCodeplug::ContactElement.</td></tr>
* <tr><td>0x197e40</td> <td>0x1a0000</td> <td>0x081c0</td> <td>Reserved, filled with @c 0xff. </td></tr>
* </table>
*
* @ingroup dm1701 */
class DM1701Codeplug : public TyTCodeplug
{
Q_OBJECT
public:
/** Extends the common @c TyTCodeplug::ChannelElement to implement the DM-1701 specific settings.
*
* Memory layout of the channel (size 0x0040 bytes):
* @verbinclude dm1701_channel.txt */
class ChannelElement: public TyTCodeplug::ChannelElement
{
protected:
/** Hidden constructor. */
ChannelElement(uint8_t *ptr, size_t size);
public:
/** Constructor. */
explicit ChannelElement(uint8_t *ptr);
void clear();
/** Returns @c true if the squelch is 'tight'. */
virtual bool tightSquelchEnabled() const;
/** Enables/disables tight squelch. */
virtual void enableTightSquelch(bool enable);
/** Returns @c true if the reversed burst is enabled. */
virtual bool reverseBurst() const;
/** Enables/disables reverse burst. */
virtual void enableReverseBurst(bool enable);
/** Returns the power of this channel. */
virtual Channel::Power power() const;
/** Sets the power of this channel. */
virtual void setPower(Channel::Power pwr);
/** Constructs a generic @c Channel object from the codeplug channel. */
Channel *toChannelObj(const ErrorStack &err=ErrorStack()) const;
/** Initializes this codeplug channel from the given generic configuration. */
void fromChannelObj(const Channel *c, Context &ctx);
};
/** Extends the @c ChannelElement to implement the VFO channel settings for the DM-1701.
* This class is an extension of the normal @c ChannelElement that only implements the step-size
* feature and encodes it where the name used to be. Thus the memory layout and size is identical
* to the normal channel. */
class VFOChannelElement: public ChannelElement
{
protected:
/** Constructor from pointer to memory. */
VFOChannelElement(uint8_t *ptr, size_t size);
public:
/** Constructor from pointer to memory. */
VFOChannelElement(uint8_t *ptr);
/** Destructor. */
virtual ~VFOChannelElement();
QString name() const;
void setName(const QString &txt);
/** Returns the step-size for the VFO channel. */
virtual unsigned stepSize() const;
/** Sets the step-size for the VFO channel in Hz. */
virtual void setStepSize(unsigned ss_hz);
};
/** Extends the common @c TyTCodeplug::GeneralSettingsElement to implement the DM-1701 specific
* settings.
*
* Memory layout of the settings (size 0x00b0 bytes):
* @verbinclude dm1701_settings.txt */
class GeneralSettingsElement: public TyTCodeplug::GeneralSettingsElement
{
protected:
/** Hidden constructor. */
GeneralSettingsElement(uint8_t *ptr, size_t size);
public:
/** Constructor. */
GeneralSettingsElement(uint8_t *ptr);
void clear();
/** Returns @c true, if VFO A is in channel mode. */
virtual bool channelModeA() const;
/** Enables/disables the channel mode for VFO A. */
virtual void enableChannelModeA(bool enable);
/** Returns @c true, if VFO B is in channel mode. */
virtual bool channelModeB() const;
/** Enables/disables the channel mode for VFO B. */
virtual void enableChannelModeB(bool enable);
/** Returns @c true, if the radio is in channel (and not VFO) mode. */
virtual bool channelMode() const;
/** Enable/disable channel mode. */
virtual void enableChannelMode(bool enable);
/** Returns @c true if group-call match is enabled. */
virtual bool groupCallMatch() const;
/** Enables/disables group-call match. */
virtual void enableGroupCallMatch(bool enable);
/** Returns @c true if private-call match is enabled. */
virtual bool privateCallMatch() const;
/** Enables/disables private-call match. */
virtual void enablePrivateCallMatch(bool enable);
/** Returns the time-zone. */
virtual QTimeZone timeZone() const;
/** Sets the time-zone. */
virtual void setTimeZone(const QTimeZone &zone);
/** Returns the channel hang time in ms. */
virtual unsigned channelHangTime() const;
/** Sets the channel hang time in ms. */
virtual void setChannelHangTime(unsigned dur);
/** Encodes the general settings. */
virtual bool fromConfig(const Config *config);
/** Updates config from general settings. */
virtual bool updateConfig(Config *config);
};
/** Extens the common @c TyTCodeplug::ButtonSettingsElement to implement the DM-1701 specific
* settings.
*
* Memory layout of the setting (size 0x0014 bytes):
* @verbinclude dm1701_buttonsettings.txt */
class ButtonSettingsElement: public TyTCodeplug::ButtonSettingsElement
{
protected:
/** Hidden constructor. */
ButtonSettingsElement(uint8_t *ptr, size_t size);
public:
/** Constructor. */
explicit ButtonSettingsElement(uint8_t *ptr);
void clear();
/** Returns the action for a short press on side button 3. */
virtual ButtonAction sideButton3Short() const;
/** Sets the action for a short press on side button 3. */
virtual void setSideButton3Short(ButtonAction action);
/** Returns the action for a long press on side button 3. */
virtual ButtonAction sideButton3Long() const;
/** Sets the action for a long press on side button 3. */
virtual void setSideButton3Long(ButtonAction action);
/** Returns the action for a short press on programmable button 1. */
virtual ButtonAction progButton1Short() const;
/** Sets the action for a short press on programmable button 1. */
virtual void setProgButton1Short(ButtonAction action);
/** Returns the action for a long press on programmable button 1. */
virtual ButtonAction progButton1Long() const;
/** Sets the action for a long press on programmable button 1. */
virtual void setProgButton1Long(ButtonAction action);
/** Returns the action for a short press on programmable button 2. */
virtual ButtonAction progButton2Short() const;
/** Sets the action for a short press on programmable button 2. */
virtual void setProgButton2Short(ButtonAction action);
/** Returns the action for a long press on programmable button 2. */
virtual ButtonAction progButton2Long() const;
/** Sets the action for a long press on programmable button 2. */
virtual void setProgButton2Long(ButtonAction action);
/** Encodes the button settings. */
virtual bool fromConfig(const Config *config);
/** Updates config from button settings. */
virtual bool updateConfig(Config *config);
};
/** Extended zone data for the DM-1701.
* The zone definition @c ZoneElement contains only a single set of 16 channels. For each zone
* definition, there is a zone extension which extends a zone to zwo sets of 64 channels each.
*
* Memory layout of encoded zone extension:
* @verbinclude dm1701_zoneext.txt */
class ZoneExtElement: public Codeplug::Element
{
protected:
/** Constructor. */
ZoneExtElement(uint8_t *ptr, size_t size);
public:
/** Constructor. */
ZoneExtElement(uint8_t *ptr);
/** Destructor. */
virtual ~ZoneExtElement();
void clear();
/** Returns the n-th member index of the channel list for A. */
virtual uint16_t memberIndexA(unsigned n) const;
/** Sets the n-th member index of the channel list for A. */
virtual void setMemberIndexA(unsigned n, uint16_t idx);
/** Returns the n-th member index of the channel list for B. */
virtual uint16_t memberIndexB(unsigned n) const;
/** Returns the n-th member index of the channel list for B. */
virtual void setMemberIndexB(unsigned n, uint16_t idx);
/** Encodes the given zone. */
virtual bool fromZoneObj(const Zone *zone, Context &ctx);
/** Links the given zone object.
* That is, extends channel list A and populates channel list B. */
virtual bool linkZoneObj(Zone *zone, Context &ctx);
};
public:
/** Constructor. */
explicit DM1701Codeplug(QObject *parent = nullptr);
/** Destructor. */
virtual ~DM1701Codeplug();
public:
void clearTimestamp();
bool encodeTimestamp();
void clearGeneralSettings();
bool encodeGeneralSettings(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
bool decodeGeneralSettings(Config *config, const ErrorStack &err=ErrorStack());
void clearChannels();
bool encodeChannels(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
bool createChannels(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
bool linkChannels(Context &ctx, const ErrorStack &err=ErrorStack());
void clearContacts();
bool encodeContacts(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
bool createContacts(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
void clearZones();
bool encodeZones(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
bool createZones(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
bool linkZones(Context &ctx, const ErrorStack &err=ErrorStack());
void clearGroupLists();
bool encodeGroupLists(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
bool createGroupLists(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
bool linkGroupLists(Context &ctx, const ErrorStack &err=ErrorStack());
void clearScanLists();
bool encodeScanLists(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
bool createScanLists(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
bool linkScanLists(Context &ctx, const ErrorStack &err=ErrorStack());
void clearButtonSettings();
bool encodeButtonSettings(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
bool decodeButtonSetttings(Config *config, const ErrorStack &err=ErrorStack());
void clearPositioningSystems();
bool encodePositioningSystems(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err);
bool createPositioningSystems(Config *config, Context &ctx, const ErrorStack &err);
bool linkPositioningSystems(Context &ctx, const ErrorStack &err);
void clearPrivacyKeys();
bool encodePrivacyKeys(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err);
bool decodePrivacyKeys(Config *config, Context &ctx, const ErrorStack &err);
void clearTextMessages();
bool encodeTextMessages(Context &ctx, const Flags &flags, const ErrorStack &err);
bool decodeTextMessages(Context &ctx, const ErrorStack &err);
void clearMenuSettings();
void clearEmergencySystems();
/** Resets VFO settings. */
virtual void clearVFOSettings();
protected:
/** Some internal offsets within the codeplug. */
struct Offset {
/// @cond DO_NOT_DOCUMENT
static constexpr unsigned int messages() { return 0x002180; }
/// @endcond
};
};
#endif // DM1701_CODEPLUG_HH
|