From 09188047c9a01dabe6bff6dfe4f3de521d51b521 Mon Sep 17 00:00:00 2001 From: Serge Vakulenko Date: Mon, 10 Sep 2018 18:50:55 -0700 Subject: [PATCH] Add support for MD-UV390 and MD-9600. Add option "-l": list all supported devices. --- main.c | 9 ++++++++- radio.c | 57 +++++++++++++++++++++++++++++++++++++-------------------- radio.h | 7 +++++++ uv380.c | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 21 deletions(-) diff --git a/main.c b/main.c index 8b4b042..9357024 100644 --- a/main.c +++ b/main.c @@ -60,6 +60,7 @@ void usage() fprintf(stderr, _(" -w Write codeplug to the radio.\n")); fprintf(stderr, _(" -c Configure the radio from a text script.\n")); fprintf(stderr, _(" -u Update contacts database.\n")); + fprintf(stderr, _(" -l List all supported radios.\n")); fprintf(stderr, _(" -t Trace USB protocol.\n")); exit(-1); } @@ -67,6 +68,7 @@ void usage() int main(int argc, char **argv) { int read_flag = 0, write_flag = 0, config_flag = 0, csv_flag = 0; + int list_flag = 0; // Set locale and message catalogs. setlocale(LC_ALL, ""); @@ -82,12 +84,13 @@ int main(int argc, char **argv) copyright = _("Copyright (C) 2018 Serge Vakulenko KK6ABQ"); trace_flag = 0; for (;;) { - switch (getopt(argc, argv, "tcwru")) { + switch (getopt(argc, argv, "tcwrul")) { case 't': ++trace_flag; continue; case 'r': ++read_flag; continue; case 'w': ++write_flag; continue; case 'c': ++config_flag; continue; case 'u': ++csv_flag; continue; + case 'l': ++list_flag; continue; default: usage(); case EOF: @@ -97,6 +100,10 @@ int main(int argc, char **argv) } argc -= optind; argv += optind; + if (list_flag) { + radio_list(); + exit(0); + } if (read_flag + write_flag + config_flag + csv_flag > 1) { fprintf(stderr, "Only one of -r, -w, -c or -u options is allowed.\n"); usage(); diff --git a/radio.c b/radio.c index 6d33186..dabb2e4 100644 --- a/radio.c +++ b/radio.c @@ -35,6 +35,21 @@ #include "radio.h" #include "util.h" +static struct { + char *ident; + radio_device_t *device; +} radio_tab[] = { + { "DR780", &radio_md380 }, // TYT MD-380, Retevis RT3, RT8 + { "MD-UV380", &radio_uv380 }, // TYT MD-UV380 + { "MD-UV390", &radio_uv390 }, // TYT MD-UV390, Retevis RT3S + { "2017", &radio_md2017 }, // TYT MD-2017, Retevis RT82 + { "MD9600", &radio_md9600 }, // TYT MD-9600 + { "ZD3688", &radio_d900 }, // Zastone D900 + { "TP660", &radio_dp880 }, // Zastone DP880 + { "ZN><:", &radio_rt27d }, // Radtel RT-27D + { 0, 0 } +}; + unsigned char radio_mem [1024*1024]; // Radio memory contents, up to 1Mbyte int radio_progress; // Read/write progress counter @@ -67,32 +82,34 @@ void radio_connect() { // Only TYT MD family for now. const char *ident = dfu_init(0x0483, 0xdf11); + int i; - if (strcasecmp(ident, "DR780") == 0) { // TYT MD-380, Retevis RT3, RT8 - device = &radio_md380; - } else - if (strcasecmp(ident, "ZD3688") == 0) { // Zastone D900 - device = &radio_d900; - } else - if (strcasecmp(ident, "TP660") == 0) { // Zastone DP880 - device = &radio_dp880; - } else - if (strcasecmp(ident, "ZN><:") == 0) { // Radtel RT-27D - device = &radio_rt27d; - } else - if (strcasecmp(ident, "2017") == 0) { // TYT MD-2017, Retevis RT82 - device = &radio_md2017; - } else - if (strcasecmp(ident, "MD-UV380") == 0) { // TYT MD-UV380 - device = &radio_uv380; - } else { - fprintf(stderr, "Unrecognized radio '%s'.\n", - ident); + for (i=0; radio_tab[i].ident; i++) { + if (strcasecmp(ident, radio_tab[i].ident) == 0) { + device = radio_tab[i].device; + break; + } + } + if (! device) { + fprintf(stderr, "Unrecognized radio '%s'.\n", ident); exit(-1); } fprintf(stderr, "Connect to %s.\n", device->name); } +// +// List all supported radios. +// +void radio_list() +{ + int i; + + printf("Supported radios:\n"); + for (i=0; radio_tab[i].ident; i++) { + printf(" %s\n", radio_tab[i].device->name); + } +} + // // Read firmware image from the device. // diff --git a/radio.h b/radio.h index 474dd3c..722c3cb 100644 --- a/radio.h +++ b/radio.h @@ -82,6 +82,11 @@ void radio_verify_config(void); // void radio_write_csv(const char *filename); +// +// List all supported radios. +// +void radio_list(void); + // // Device-dependent interface to the radio. // @@ -107,6 +112,8 @@ struct _radio_device_t { extern radio_device_t radio_md380; // TYT MD-380 extern radio_device_t radio_md2017; // TYT MD-2017 extern radio_device_t radio_uv380; // TYT MD-UV380 +extern radio_device_t radio_uv390; // TYT MD-UV390 +extern radio_device_t radio_md9600; // TYT MD-9600 extern radio_device_t radio_d900; // Zastone D900 extern radio_device_t radio_dp880; // Zastone DP880 extern radio_device_t radio_rt27d; // Radtel RT-27D diff --git a/uv380.c b/uv380.c index 18177e2..d04d4fb 100644 --- a/uv380.c +++ b/uv380.c @@ -2526,6 +2526,26 @@ radio_device_t radio_uv380 = { uv380_write_csv, }; +// +// TYT MD-UV390 +// +radio_device_t radio_uv390 = { + "TYT MD-UV390", + uv380_download, + uv380_upload, + uv380_is_compatible, + uv380_read_image, + uv380_save_image, + uv380_print_version, + uv380_print_config, + uv380_verify_config, + uv380_parse_parameter, + uv380_parse_header, + uv380_parse_row, + uv380_update_timestamp, + uv380_write_csv, +}; + // // TYT MD-2017 // @@ -2545,3 +2565,23 @@ radio_device_t radio_md2017 = { uv380_update_timestamp, uv380_write_csv, }; + +// +// TYT MD-9600 +// +radio_device_t radio_md9600 = { + "TYT MD-9600", + uv380_download, + uv380_upload, + uv380_is_compatible, + uv380_read_image, + uv380_save_image, + uv380_print_version, + uv380_print_config, + uv380_verify_config, + uv380_parse_parameter, + uv380_parse_header, + uv380_parse_row, + uv380_update_timestamp, + uv380_write_csv, +};