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
|
#ifndef MD2017_CODEPLUG_HH
#define MD2017_CODEPLUG_HH
#include "tyt_codeplug.hh"
#include "uv390_codeplug.hh"
/** Device specific implementation of the codeplug for the TyT MD-2017.
*
* 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 md2017cpl 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 TyTCodeplug::GeneralSettingsElement.</td></tr>
* <tr><td>0x0020f0</td> <td>0x002100</td> <td>0x00010</td> <td>Menu settings, see @c UV390Codeplug::menu_t</td></tr>
* <tr><td>0x002100</td> <td>0x002140</td> <td>0x00040</td> <td>Button config, see @c UV390Codeplug::buttons_t.</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, see @c UV390Codeplug::message_t.</td></tr>
* <tr><td>0x0059c0</td> <td>0x005a70</td> <td>0x000b0</td> <td>Privacy keys, see @c UV390Codeplug::privacy_t.</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 TyTCodeplug::VFOChannelElement.</td></tr>
* <tr><td>0x02ef40</td> <td>0x02ef80</td> <td>0x00040</td> <td>VFO B channel, see @c TyTCodeplug::VFOChannelElement.</td></tr>
* <tr><td>0x02ef80</td> <td>0x02f000</td> <td>0x00080</td> <td>Reserved, filled with @c 0xff. </td></tr>
* <tr><td>0x02f000</td> <td>0x02f010</td> <td>0x00010</td> <td>Some unknown settings like current channel, see @c TyTCodeplug::BootSettingsElement.</td></tr>
* <tr><td>0x02f010</td> <td>0x031000</td> <td>0x01ff0</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 TyTCodeplug::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 TyTCodeplug::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 md2017 */
class MD2017Codeplug : public TyTCodeplug
{
Q_OBJECT
public:
/** Reuse TyT MD-UV390 channel element. */
typedef UV390Codeplug::ChannelElement ChannelElement;
/** Reuse TyT MD-UV390 VFO channel element. */
typedef UV390Codeplug::VFOChannelElement VFOChannelElement;
/** Reuse TyT MD-UV390 zone extension element. */
typedef UV390Codeplug::ZoneExtElement ZoneExtElement;
/** Reuse TyT MD-UV390 boot settings element. */
typedef UV390Codeplug::BootSettingsElement BootSettingsElement;
/** Reuse TyT MD-UV390 menu settings element. */
typedef UV390Codeplug::MenuSettingsElement MenuSettingsElement;
/** Contact element for MD2017 codeplugs.
*
* This class implements the same memory layout as the base TyTCodeplug::ContactElement. It just
* overrides the @c isValid method.
*
* Memory layout of encoded contact:
* @verbinclude tyt_contact.txt */
class ContactElement: public TyTCodeplug::ContactElement
{
protected:
/** Hidden constructor. */
ContactElement(uint8_t *ptr, size_t size);
public:
/** Constructor. */
ContactElement(uint8_t *ptr);
bool isValid() const;
};
public:
/** Constructor. */
explicit MD2017Codeplug(QObject *parent = nullptr);
/** Destructor. */
virtual ~MD2017Codeplug();
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 clearPositioningSystems();
bool encodePositioningSystems(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
bool createPositioningSystems(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
bool linkPositioningSystems(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 clearPrivacyKeys();
bool encodePrivacyKeys(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err);
bool decodePrivacyKeys(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
void clearTextMessages();
bool encodeTextMessages(Context &ctx, const Flags &flags, const ErrorStack &err);
bool decodeTextMessages(Context &ctx, const ErrorStack &err);
/** Resets/clears the boot settings. */
virtual void clearBootSettings();
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 // MD2017_CODEPLUG_HH
|