19
19
* segments must align with @c 0x400 (1024 bytes).
21
21
* @section uv390cpl Codeplug structure within radio
22
* The codeplug structure is reverse engineered almost completely and can be programmed from
23
* scratch. That is, it is not neccessary to update an existing codeplug on the radio.
23
25
* <tr><th>Start</th> <th>End</th> <th>Size</th> <th>Content</th></tr>
24
26
* <tr><th colspan="4">First segment 0x002800-0x040800</th></tr>
25
27
* <tr><td>0x002800</td> <td>0x00280c</td> <td>0x0000c</td> <td>Timestamp see @c UV390Codeplug::timestamp_t.</td></tr>
26
28
* <tr><td>0x00280c</td> <td>0x002840</td> <td>0x00034</td> <td>Reserved, filled with 0xff. </td></tr>
27
* <tr><td>0x002840</td> <td>0x0028e4</td> <td>0x000a4</td> <td>General settings see @c UV390Codeplug::general_settings_t.</td></tr>
28
* <tr><td>0x0028e4</td> <td>0x002980</td> <td>0x0009c</td> <td>??? Unknown ???</td></tr>
29
* <tr><td>0x002840</td> <td>0x0028f0</td> <td>0x000b0</td> <td>General settings see @c UV390Codeplug::general_settings_t.</td></tr>
30
* <tr><td>0x0028f0</td> <td>0x002900</td> <td>0x00010</td> <td>Menu settings, see @c UV390Codeplug::menu_t</td></tr>
31
* <tr><td>0x002900</td> <td>0x002940</td> <td>0x00040</td> <td>Button config, see @c UV390Codeplug::buttons_t.</td></tr>
32
* <tr><td>0x002940</td> <td>0x002980</td> <td>0x00040</td> <td>Reserved, filled with 0xff.</td></tr>
29
33
* <tr><td>0x002980</td> <td>0x0061c0</td> <td>0x03840</td> <td>50 Text messages @ 0x120 bytes each, see @c UV390Codeplug::message_t.</td></tr>
30
* <tr><td>0x0061c0</td> <td>0x00f420</td> <td>0x09260</td> <td>??? Unknown ???</td></tr>
34
* <tr><td>0x0061c0</td> <td>0x006270</td> <td>0x000b0</td> <td>Privacy keys, see @c UV390Codeplug::privacy_t.</td></tr>
35
* <tr><td>0x006250</td> <td>0x006760</td> <td>0x00510</td> <td>Emergency Systems, see @c UV390Codeplug::emergency_t.</td></td>
36
* <tr><td>0x006760</td> <td>0x00f420</td> <td>0x08cc0</td> <td>Reserved, filled with 0xff.</td></td>
31
37
* <tr><td>0x00f420</td> <td>0x0151e0</td> <td>0x05dc0</td> <td>250 RX Group lists @ 0x60 bytes each, see @c UV390Codeplug::grouplist_t.</td></tr>
32
38
* <tr><td>0x0151e0</td> <td>0x019060</td> <td>0x03e80</td> <td>250 Zones @ 0x40 bytes each, see @c UV390Codeplug::zone_t.</td></tr>
33
39
* <tr><td>0x019060</td> <td>0x01f5f0</td> <td>0x06590</td> <td>250 Scanlists @ 0x68 bytes each, see @c UV390Codeplug::scanlist_t.</td></tr>
34
40
* <tr><td>0x01f5f0</td> <td>0x02f700</td> <td>0x10110</td> <td>Reserved, filled with @c 0xff. </td></tr>
35
* <tr><td>0x02f700</td> <td>0x02f780</td> <td>0x00080</td> <td>??? Unknown. ???</td></tr>
36
* <tr><td>0x02f780</td> <td>0x02f800</td> <td>0x00080</td> <td>Reserved, filled with @c 0xff. </td></tr>
37
* <tr><td>0x02f800</td> <td>0x030b88</td> <td>0x01388</td> <td>??? Unknown. ???</td></tr>
38
* <tr><td>0x030b88</td> <td>0x031800</td> <td>0x00c78</td> <td>Reserved, filled with @c 0xff. </td></tr>
41
* <tr><td>0x02f700</td> <td>0x02f740</td> <td>0x00040</td> <td>VFO A channel, see @c UV390Codeplug::channel_t.</td></tr>
42
* <tr><td>0x02f740</td> <td>0x02f780</td> <td>0x00040</td> <td>VFO B channel, see @c UV390Codeplug::channel_t.</td></tr>
43
* <tr><td>0x02f780</td> <td>0x030800</td> <td>0x01080</td> <td>Reserved, filled with @c 0xff. </td></tr>
44
* <tr><td>0x030800</td> <td>0x030b80</td> <td>0x00380</td> <td>??? Unknown. DTMF Systems? ???</td></tr>
45
* <tr><td>0x030b80</td> <td>0x031800</td> <td>0x00c80</td> <td>Reserved, filled with @c 0xff. </td></tr>
39
46
* <tr><td>0x031800</td> <td>0x03f2c0</td> <td>0x0dac0</td> <td>250 Zone-extensions @ 0xe0 bytes each, see @c UV390Codeplug::zone_ext_t.</td></tr>
40
* <tr><td>0x03f2c0</td> <td>0x03f40e</td> <td>0x0014e</td> <td>??? Unknown ???</td></tr>
41
* <tr><td>0x03f40e</td> <td>0x03f50e</td> <td>0x00100</td> <td>16 GPS systems @ 0x10 bytes each, see @c UV390Codeplug::gpssystem_t.</td></tr>
42
* <tr><td>0x03f50e</td> <td>0x040800</td> <td>0x012f2</td> <td>??? Unknown ???</td></tr>
47
* <tr><td>0x03f2c0</td> <td>0x03f440</td> <td>0x00180</td> <td>Reserved, filled with @c 0xff. </td></tr>
48
* <tr><td>0x03f440</td> <td>0x03f540</td> <td>0x00100</td> <td>16 GPS systems @ 0x10 bytes each, see @c UV390Codeplug::gpssystem_t.</td></tr>
49
* <tr><td>0x03f540</td> <td>0x040800</td> <td>0x012c0</td> <td>Reserved, filled with @c 0xff. </td></tr>
43
50
* <tr><th colspan="4">Second segment 0x110800-0x1a0800</th></tr>
44
51
* <tr><td>0x110800</td> <td>0x13f600</td> <td>0x2ee00</td> <td>3000 Channels @ 0x40 bytes each, see @c UV390Codeplug::channel_t.</td></tr>
45
52
* <tr><td>0x13f600</td> <td>0x140800</td> <td>0x01200</td> <td>Reserved, filled with @c 0xff. </td></tr>
46
53
* <tr><td>0x140800</td> <td>0x198640</td> <td>0x57e40</td> <td>10000 Contacts @ 0x24 bytes each, see @c UV390Codeplug::contact_t.</td></tr>
47
54
* <tr><td>0x198640</td> <td>0x1a0800</td> <td>0x081c0</td> <td>Reserved, filled with @c 0xff. </td></tr>
55
* <tr><th colspan="4">Callsign database 0x0200000-0x1000000</th></tr>
56
* <tr><td>0x200000</td> <td>0x204004</td> <td>0x04004</td> <td>Callsign database index table, see @c UV390Codeplug::callsign_db_t</td></tr>
57
* <tr><td>0x204004</td> <td>0xffffdc</td> <td>0xdfbfd8</td> <td>122197 callsign database entries, see @c UV390Codeplug::callsign_db_t::callsign_t. </td></tr>
58
* <tr><td>0xffffdc</td> <td>0x1000000</td> <td>0x00025</td> <td>Padding, filled with @c 0xff.</td></tr>
50
61
* @ingroup uv390 */
627
687
void fromGPSSystemObj(const GPSSystem *l, const Config *conf);
630
/** Represents an entry within the callsign database.
631
* @todo Implement generic config representation for callsign database. */
632
struct __attribute__((packed)) callsign_t {
633
uint32_t dmrid : 24, ///< DMR id in BCD
634
_unused : 8; ///< Unknown set to 0xff.
635
char callsign[16]; ///< ASCII zero-terminated
636
char name[100]; ///< Descriptive name, nickname, city, state, country.
690
/** Represents all menu settings within the codeplug on the radio. */
691
struct __attribute__((packed)) menu_t {
692
uint8_t hangtime; ///< Specifies the menu hang-time in seconds, [0,30], 0=infinite.
693
uint8_t text_message : 1, ///< Show text message menu, 0=hide, 1=show.
694
call_alert : 1, ///< Contact call-alert.
695
contacts_edit : 1, ///< Contacts edit.
696
manual_dial : 1, ///< Manual dial.
697
radio_check : 1, ///< Contacts radio-check.
698
remote_monitor : 1, ///< Remote monitor.
699
radio_enable : 1, ///< Radio enable.
700
radio_disable : 1; ///< Radio disable.
701
uint8_t _reserved_2_0 : 1, ///< Reverved, set to 1.
702
scan : 1, ///< Show scan settings.
703
edit_scan_list : 1, ///< Show edit scan list.
704
calllog_missed : 1, ///< Call-log missed.
705
calllog_answered : 1, ///< Call-log answered.
706
calllog_outgoing : 1, ///< Call-log outgoing.
707
talkaround : 1, ///< Talkaround.
708
tone_or_alert : 1; ///< Tone or Alert.
709
uint8_t power : 1, ///< Power.
710
backlight : 1, ///< Backlight.
711
intro_screen : 1, ///< Introscreen.
712
keypad_lock : 1, ///< Key-pad lock.
713
led_indicator : 1, ///< LED indicator.
714
squelch : 1, ///< Squelch.
715
_unknown_3_6 : 1, ///< Unknown, set to 0.
716
vox : 1; ///< Show VOX settings.
717
uint8_t password : 1, ///< Show password and lock settings.
718
display_mode : 1, ///< Show display mode settings.
719
hide_prog_radio : 1, ///< Hide programm radio settings.
720
_unknown_4_3 : 1, ///< Unknown, set to 0b1.
721
hide_gps : 1, ///< Hide GPS settings.
722
record_switch : 1, ///< Show record switch settings.
723
_unknown_4_6 : 2; ///< Unknown, set to 0b11.
724
uint8_t _unknown_5_0 : 2, ///< Uknnown, set to 0b11.
725
group_call_match : 1, ///< Show Group-call match settings.
726
private_call_match : 1, ///< Show Private-call match settings.
727
menu_hangtime : 1, ///< Show menu hangtime settings.
728
tx_mode : 1, ///< Show TX mode settings.
729
zone : 1, ///< Show zone settings.
730
new_zone : 1; ///< Show new zone settings.
731
uint8_t edit_zone : 1, ///< Show edit zone settings.
732
new_scan_list : 1, ///< New scan list.
733
_unknown_6_2 : 6; ///< Unknown, set to 0xb111111.
735
uint8_t _reserved_7[9]; ///< Reserved, filled with 0xff.
737
/** Default constructor. */
739
/** Clears and resets all menu settings to default values (all ham-radio related menus are enabled). */
743
/** Represents all button settings within the codeplug on the radio. */
744
struct __attribute__((packed)) buttons_t {
745
/** Possible actions for the side-buttons. */
747
Disabled = 0, ///< Disabled side-button action.
748
ToggleAllAlertTones = 1, ///< Toggle all alert tones.
749
EmergencyOn = 2, ///< Enable emergency.
750
EmergencyOff = 3, ///< Disable emergency.
751
PowerSelect = 4, ///< Select TX power.
752
MonitorToggle = 5, ///< Toggle monitor (promiscuous mode on digital channel, open squelch on analog channel).
753
OneTouch1 = 7, ///< Perform one-touch action 1.
754
OneTouch2 = 8, ///< Perform one-touch action 2.
755
OneTouch3 = 9, ///< Perform one-touch action 3.
756
OneTouch4 = 10, ///< Perform one-touch action 4.
757
OneTouch5 = 11, ///< Perform one-touch action 5.
758
OneTouch6 = 12, ///< Perform one-touch action 6.
759
RepeaterTalkaroundToggle = 13, ///< Toggle repater mode / talkaround.
760
ScanToggle = 14, ///< Start/stop scan.
761
SquelchToggle = 21, ///< Enable/disable squelch.
762
PrivacyToggle = 22, ///< Enable/disable privacy system.
763
VoxToggle = 23, ///< Enable/disable VOX.
764
ZoneIncrement = 24, ///< Switch to next zone.
765
BatteryIndicator = 26, ///< Show battery charge.
766
LoneWorkerToggle = 31, ///< Toggle lone-worker.
767
RecordToggle = 34, ///< Enable/disable recording (dep. on firmware).
768
RecordPlayback = 35, ///< Start/stop playback.
769
RecordDeleteAll = 36, ///< Delete all recordings.
770
Tone1750Hz = 38, ///< Send 1750Hz tone.
771
SwitchUpDown = 47, ///< Switch Channel A/B.
772
RightKey = 48, ///< Who knows?
773
LeftKey = 49, ///< Who knows?
774
ZoneDecrement = 55 ///< Switch to previous zone.
777
/** Represents a single one-touch setting within the codeplug on the radio. */
778
struct __attribute__((packed)) one_touch_t {
779
/** Possible one-touch actions. */
781
CALL = 0b0000, ///< Call someone, see @c contact.
782
MESSAGE = 0b0001, ///< Send a message, see @c message.
783
DTMF1 = 0b1000, ///< Analog call DTMF system 1.
784
DTMF2 = 0b1001, ///< Analog call DTMF system 2.
785
DTMF3 = 0b1010, ///< Analog call DTMF system 3.
786
DTMF4 = 0b1011 ///< Analog call DTMF system 4.
789
/** Possible one-touch action types. */
791
Disabled = 0b00, ///< Disabled one-touch.
792
Digital = 0b01, ///< Digital call/message.
793
Analog = 0b10 ///< Analog call.
796
uint8_t action : 4, ///< Action 0b0000=call, 0b0001=message, 0b1000=DTMF1, 0b1001=DTMF2, 0b1010=DTMF3, 0b1011=DTMF4
797
type : 2, ///< Type, 0b00=Disabled, 0b01=Digital, 0b10=Analog
798
_reserved_0_6 : 2; ///< Reserved, set to 0b11;
799
uint8_t message; ///< Message idx+1, 0=none.
800
uint16_t contact; ///< Contact idx+1, 0=none.
802
/** Resets this one-touch action settings. */
806
uint16_t _reserved_0; ///< Reserved, set to 0x0000.
807
uint8_t side_button_1; ///< Side button 1 short press, 0=disabled, see @c UV390Codeplug::buttons_t::ButtonAction.
808
uint8_t side_button_1_long; ///< Side button 1 long press, 0=disabled, see @c UV390Codeplug::buttons_t::ButtonAction.
809
uint8_t side_button_2; ///< Side button 2 short press, 0=disabled, see @c UV390Codeplug::buttons_t::ButtonAction.
810
uint8_t side_button_2_long; ///< Side button 2 long press, 0=disabled, see @c UV390Codeplug::buttons_t::ButtonAction.
811
uint8_t _unused_6[10]; ///< Unknown set to 0x00.
812
uint8_t _unknown_16; ///< Unkown set to 0x01;
813
uint8_t long_press_dur; ///< Long-press duration in 250ms steps, range [0x04,0x0f], default 0x04.
815
uint16_t _unused_18; ///< Unused set to 0xffff;
817
one_touch_t one_touch[6]; ///< One-touch settings 1-6.
819
uint8_t _unused_42[20]; ///< Unkown set to 0x00;
821
/** Default constructor. */
823
/** Clears the button settings.
824
* Sets side button 1 (long press) to 1750Hz tone and side button 2 (short press) to monitor
829
/** Represents the emergency settings within the codeplug on the radio. */
830
struct __attribute__((packed)) emergency_t {
831
/** Represents a single emergency system within the radio. */
832
struct __attribute__((packed)) system_t {
833
/** Possible alarm type for the system. */
835
DISABLED = 0, ///< No alarm at all
836
REGULAR = 1, ///< Regular alarm sound.
837
SILENT = 2, ///< Silent alarm.
838
SILENT_W_VOICE = 3 ///< silent alarm with voice.
840
/** Possible alarm modes for the system. */
842
ALARM = 0, ///< Just alarm.
843
ALARM_W_CALL = 1, ///< Alarm + call.
844
ALARM_W_VOICE = 2 ///< Alarm + call + voice?
847
uint16_t name[16]; ///< System name 16 x 16bit unicode 0x0000 terminated.
848
uint8_t alarm_type : 2, ///< Alarm type.
849
_unknown_32_2 : 2, ///< Unknown set to 0b11
850
alarm_mode : 2, ///< Alarm mode.
851
_unknown_32_6 : 2; ///< Unknown set to 0b01
852
uint8_t impolite_retires; ///< Number of impolite retries [1-15], default=15.
853
uint8_t polite_retries; ///< Number of polite retires [0-14], default=5, 0x0f=infinite.
854
uint8_t hot_mic_dur; ///< Hot microphone duration in seconds in 10s steps, [10-120], default=10.
855
uint16_t revert_channel; ///< Revert channel index+1, 0xfffe Selected, 0x0000 System disabled.
856
uint16_t _unused_37; ///< Unused, set to 0xffff.
858
/** Default constructor. */
860
/** Resets and invalidates emergency system. */
862
/** Retruns true, if the emergency system is valid (enabled). */
863
bool isValid() const;
866
uint8_t radio_dis_dec : 1, ///< Radio disable decode, 0=off, 1=on, default=1.
867
remote_mon_decode : 1, ///< Remote monitor decode, 0=off, 1=on, default=0.
868
em_remote_mon_decode : 1, ///< Emergency remote monitor decode, 0=off, 1=on, default=0.
869
_unknown_0_3 : 5; ///< Unknown, set to 0b11111.
870
uint8_t remote_mon_dur; ///< Duration in seconds in 10s steps [20-120].
871
uint8_t tx_sync_wakeup_tot; ///< TOT in ms in 25ms steps. [5-15].
872
uint8_t tx_wakeup_msg_limit; ///< Message limit [1-3].
873
uint8_t _unused_4[12]; ///< Unused 12bytes set to 0xff;
874
system_t systems[32]; ///< 32 x system_t Emergency systems.
876
/** Default constructor also disables all systems. */
878
/** Clears and resets all emergency system settings. */
882
/** Represents all privacy settings within the codeplug on the device. */
883
struct __attribute__((packed)) privacy_t {
884
uint8_t enhanced_keys[8][16]; ///< 8 x 16-byte enhanced keys. Filled with 0xff by default.
885
uint8_t _reserved[16]; ///< Unused/reserved space 16-byte filled with 0xff.
886
uint8_t basic_keys[16][2]; ///< 16 x 2-byte basic keys. Filled with 0xff by default.
888
/** Default constructor. */
890
/** Resets all privacy keys. */
894
/** Represents a search index over the complete callsign database.
896
* Memmory layout of encoded Callsign/User database:
897
* @verbinclude uv390userdb.txt
899
struct __attribute__((packed)) callsign_db_t {
900
/** Represents an index entry, a pair of DMR ID and callsign DB index.
902
* Memmory layout of encoded Callsign/User database index entry:
903
* @verbinclude uv390userdbentry.txt
905
struct __attribute__((packed)) entry_t {
906
uint32_t id_high: 12, ///< High bits of DMR ID (23:12).
907
index: 20; ///< Index in callsign data base, where to find these.
909
/// Empty constructor.
912
/** Clears this entry. */
914
/** Returns true, if the database index entry is valid. */
915
bool isValid() const;
918
/** Represents an entry within the callsign database.
919
* The callsign DB entries must be ordered by their DMR id.
921
* Memmory layout of encoded Callsign/User database index entry:
922
* @verbinclude uv390userdbcallsign.txt
924
struct __attribute__((packed)) callsign_t {
925
uint8_t dmrid[3]; ///< DMR id in BCD
926
uint8_t _unused; ///< Unused set to 0xff.
927
char callsign[16]; ///< 16 x ASCII zero-terminated.
928
char name[100]; ///< Descriptive name, nickname, city, state, country. 100 x ASCII zero-terminated.
931
/// Empty constructor.
934
/// Clears the DB entry.
936
/// Returns @c true if entry is valid.
937
bool isValid() const;
938
/** Sets the ID of the entry. */
939
void setID(uint32_t dmrid);
940
/** Sets the call of the entry. */
941
void setCall(const QString &call);
942
/** Sets the name, city, country etc. of the entry. */
943
void setName(const QString &name);
944
/** Constructs an entry from the given user. */
945
void fromUser(const UserDatabase::User &user);
948
uint32_t n : 24; ///< Number of contacts in compete database.
949
entry_t index[4096]; ///< 4096 index entries, default 0xff.
950
callsign_t db[122197]; ///< 122197 database callsign entries.
952
/// Empty constructor.
955
/// Clears the complete callsign database.
957
/// Fills the callsign database from the given user db.
958
void fromUserDB(const UserDatabase *db);
640
/** Default constructor. */
641
explicit UV390Codeplug(QObject *parent = nullptr);
962
/** Empty constructor. */
963
explicit UV390Codeplug(QObject *parent = nullptr);
965
/** Clears and resets the complete codeplug to some default values. */
643
968
/** Decodes the binary codeplug and stores its content in the given generic configuration. */
644
969
bool decode(Config *config);
645
970
/** Encodes the given generic configuration as a binary codeplug. */
646
bool encode(Config *config);
971
bool encode(Config *config);
649
974
#endif // RT3S_GPS_CODEPLUG_HH