diff --git a/kenwood/kenwood.h b/kenwood/kenwood.h index 9a92bf93e..cb6e4a84a 100644 --- a/kenwood/kenwood.h +++ b/kenwood/kenwood.h @@ -33,7 +33,7 @@ #define EOM_TH '\r' #define KENWOOD_MODE_TABLE_MAX 24 -#define KENWOOD_MAX_BUF_LEN 50 /* max answer len, arbitrary */ +#define KENWOOD_MAX_BUF_LEN 128 /* max answer len, arbitrary */ /* Tokens for Parameters common to multiple rigs. diff --git a/kenwood/tmd710.c b/kenwood/tmd710.c index b130630a6..82b8a376e 100644 --- a/kenwood/tmd710.c +++ b/kenwood/tmd710.c @@ -1,9 +1,22 @@ /* - * Hamlib Kenwood backend - TM-D710 description + * Hamlib Kenwood backend - TM-D710(G) description * Copyright (c) 2011 by Charles Suprin - * As of 4/20/16 Kenwood says the CAT protocol is "not available" - * So best guess has been used along with tmd710 info from sourceforge + * Copyright (c) 2018 Mikael Nousiainen * + * Command set specification available in: + * - https://github.com/LA3QMA/TM-V71_TM-D710-Kenwood + * - http://kd7dvd.us/equipment/tm-d710a/manuals/control_commands.pdf + * + * Limitations: + * - It is possible to set frequency only inside the selected frequency band of the current VFO, + * since there is no command to change the frequency band of a VFO + * + * Features not yet implemented: + * - DTMF send + * - Tone burst frequency setting + * - Call channel settings + * - Change between dual-band/single-band mode + * - Several miscellaneous settings available via the MU menu command, which could be exposed via extparms/extlevels * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -56,33 +69,45 @@ static int tmd710_get_mem(RIG *rig, vfo_t vfo, int *ch); static int tmd710_set_mem(RIG *rig, vfo_t vfo, int ch); static int tmd710_set_dcs_sql(RIG * rig, vfo_t vfo, tone_t code); static int tmd710_get_dcs_sql(RIG * rig, vfo_t vfo, tone_t *code); -//static int tmd710_set_channel(RIG *rig, const channel_t *chan); +static int tmd710_set_channel(RIG *rig, const channel_t *chan); static int tmd710_get_channel(RIG *rig, channel_t *chan); +static int tmd710_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); +static int tmd710_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); +static int tmd710_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); +static int tmd710_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); +static int tmd710_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); +static int tmd710_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); +static int tmd710_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); +static int tmd710_get_parm(RIG *rig, setting_t parm, value_t *val); +static int tmd710_set_parm(RIG *rig, setting_t parm, value_t val); +static int tmd710_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val); +static int tmd710_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val); -#define TMD710_MODES (RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_AM) -#define TMD710_MODES_FM (RIG_MODE_FM|RIG_MODE_FMN) -#define TMD710_MODES_TX (RIG_MODE_FM|RIG_MODE_FMN) +#define TMD710_MODES (RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_AM) +#define TMD710_MODES_FM (RIG_MODE_FM|RIG_MODE_FMN) +#define TMD710_MODES_TX (RIG_MODE_FM|RIG_MODE_FMN) -/* TBC */ -#define TMD710_FUNC_ALL (RIG_FUNC_TSQL| \ +#define TMD710_FUNC_GET (RIG_FUNC_TSQL| \ + RIG_FUNC_TONE| \ + RIG_FUNC_REV| \ + RIG_FUNC_LOCK| \ + RIG_FUNC_ARO| \ RIG_FUNC_AIP| \ - RIG_FUNC_MON| \ - RIG_FUNC_MUTE| \ - RIG_FUNC_SQL| \ + RIG_FUNC_RESUME) +#define TMD710_FUNC_SET (RIG_FUNC_TSQL| \ RIG_FUNC_TONE| \ RIG_FUNC_TBURST| \ RIG_FUNC_REV| \ RIG_FUNC_LOCK| \ - RIG_FUNC_ARO) + RIG_FUNC_ARO| \ + RIG_FUNC_AIP| \ + RIG_FUNC_RESUME) -#define TMD710_LEVEL_ALL (RIG_LEVEL_STRENGTH| \ - RIG_LEVEL_SQL| \ - RIG_LEVEL_AF| \ - RIG_LEVEL_RF|\ - RIG_LEVEL_MICGAIN) +#define TMD710_LEVEL_ALL (RIG_LEVEL_SQL| \ + RIG_LEVEL_RFPOWER) -#define TMD710_PARMS (RIG_PARM_BACKLIGHT|\ +#define TMD710_PARMS (RIG_PARM_BACKLIGHT|\ RIG_PARM_BEEP|\ RIG_PARM_APO) @@ -99,10 +124,96 @@ static int tmd710_get_channel(RIG *rig, channel_t *chan); .dcs_code=1, \ .dcs_sql=1, -/* - * TODO: Band A & B - */ -#define TMD710_VFO (RIG_VFO_A|RIG_VFO_B) +#define TOKEN_BACKEND(t) (t) + +#define TOK_LEVEL_EXT_DATA_BAND TOKEN_BACKEND(100) + +// TM-D710 protocol definitions + +#define TMD710_BAND_A 0 +#define TMD710_BAND_B 1 + +#define TMD710_BAND_MODE_VFO 0 +#define TMD710_BAND_MODE_MEMORY 1 +#define TMD710_BAND_MODE_CALL 2 +#define TMD710_BAND_MODE_WX 3 + +#define TMD710_RF_POWER_MIN 0 +#define TMD710_RF_POWER_MAX 2 + +#define TMD710_SQL_MIN 0 +#define TMD710_SQL_MAX 0x1F + +// TM-D710 MU command value tables + +#define TMD710_ANNOUNCE_OFF 0 +#define TMD710_ANNOUNCE_AUTO 1 +#define TMD710_ANNOUNCE_MANUAL 2 + +#define TMD710_LANGUAGE_ENGLISH 0 +#define TMD710_LANGUAGE_JAPANESE 1 + +#define TMD710_SMETER_HANG_UP_TIME_OFF 0 +#define TMD710_SMETER_HANG_UP_TIME_125 1 +#define TMD710_SMETER_HANG_UP_TIME_250 2 +#define TMD710_SMETER_HANG_UP_TIME_500 3 + +#define TMD710_MUTE_HANG_UP_TIME_OFF 0 +#define TMD710_MUTE_HANG_UP_TIME_125 1 +#define TMD710_MUTE_HANG_UP_TIME_250 2 +#define TMD710_MUTE_HANG_UP_TIME_500 3 +#define TMD710_MUTE_HANG_UP_TIME_750 4 +#define TMD710_MUTE_HANG_UP_TIME_1000 5 + +#define TMD710_TIMEOUT_TIMER_3MIN 0 +#define TMD710_TIMEOUT_TIMER_5MIN 1 +#define TMD710_TIMEOUT_TIMER_10MIN 2 + +#define TMD710_RECALL_METHOD_ALL 0 +#define TMD710_RECALL_METHOD_CURRENT 1 + +#define TMD710_ECHOLINK_SPEED_FAST 0 +#define TMD710_ECHOLINK_SPEED_SLOW 1 + +#define TMD710_DTMF_SPEED_FAST 0 +#define TMD710_DTMF_SPEED_SLOW 1 + +#define TMD710_DTMF_PAUSE_100 0 +#define TMD710_DTMF_PAUSE_250 1 +#define TMD710_DTMF_PAUSE_500 2 +#define TMD710_DTMF_PAUSE_750 3 +#define TMD710_DTMF_PAUSE_1000 4 +#define TMD710_DTMF_PAUSE_1500 5 +#define TMD710_DTMF_PAUSE_2000 6 + +#define TMD710_BACKLIGHT_COLOR_AMBER 0 +#define TMD710_BACKLIGHT_COLOR_GREEN 1 + +#define TMD710_SCAN_RESUME_TIME 0 +#define TMD710_SCAN_RESUME_CARRIER 1 +#define TMD710_SCAN_RESUME_SEEK 2 + +#define TMD710_AUTO_POWER_OFF_OFF 0 +#define TMD710_AUTO_POWER_OFF_30MIN 1 +#define TMD710_AUTO_POWER_OFF_60MIN 2 +#define TMD710_AUTO_POWER_OFF_90MIN 3 +#define TMD710_AUTO_POWER_OFF_120MIN 4 +#define TMD710_AUTO_POWER_OFF_180MIN 5 + +#define TMD710_EXT_DATA_BAND_A 0 +#define TMD710_EXT_DATA_BAND_B 1 +#define TMD710_EXT_DATA_BAND_TXA_RXB 2 +#define TMD710_EXT_DATA_BAND_TXB_RXA 3 + +#define TMD710_EXT_DATA_SPEED_1200 0 +#define TMD710_EXT_DATA_SPEED_9600 1 + +#define TMD710_SQC_SOURCE_OFF 0 +#define TMD710_SQC_SOURCE_BUSY 1 +#define TMD710_SQC_SOURCE_SQL 2 +#define TMD710_SQC_SOURCE_TX 3 +#define TMD710_SQC_SOURCE_BUSY_OR_TX 4 +#define TMD710_SQC_SOURCE_SQL_OR_TX 5 static rmode_t tmd710_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, @@ -115,168 +226,172 @@ static struct kenwood_priv_caps tmd710_priv_caps = { .mode_table = tmd710_mode_table, }; - - -/* - * TM-D710 rig capabilities. +/* Private TM-D710 extra levels definitions * - * specs: - * protocol: kd7dvd.us/equipment/tm-d710a/manuals/control_commands.pdf + * Token definitions for .cfgparams in rig_caps + * See enum rig_conf_e and struct confparams in rig.h */ -const struct rig_caps tmd710_caps = { -.rig_model = RIG_MODEL_TMD710, -.model_name = "TM-D710", -.mfg_name = "Kenwood", -.version = "0.6b", -.copyright = "LGPL", -.status = RIG_STATUS_BETA, -.rig_type = RIG_TYPE_MOBILE|RIG_FLAG_APRS|RIG_FLAG_TNC, -.ptt_type = RIG_PTT_RIG, -.dcd_type = RIG_DCD_RIG, -.port_type = RIG_PORT_SERIAL, -.serial_rate_min = 9600, -.serial_rate_max = 57600, -.serial_data_bits = 8, -.serial_stop_bits = 1, -.serial_parity = RIG_PARITY_NONE, -.serial_handshake = RIG_HANDSHAKE_NONE, -.write_delay = 0, -.post_write_delay = 0, -.timeout = 1000, -.retry = 3, - -.has_get_func = TMD710_FUNC_ALL, -.has_set_func = TMD710_FUNC_ALL, -.has_get_level = TMD710_LEVEL_ALL, -.has_set_level = RIG_LEVEL_SET(TMD710_LEVEL_ALL), -.has_get_parm = TMD710_PARMS, -.has_set_parm = TMD710_PARMS, /* FIXME: parms */ -.level_gran = { - [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 7 } }, - [LVL_SQL] = { .min = { .i = 0 }, .max = { .i = 0x1f }, .step = { .f = 1./0x1f } }, - [LVL_RFPOWER] = { .min = { .i = 2 }, .max = { .i = 0 }, .step = { .f = 1./3. } }, - [LVL_AF] = { .min = { .i = 0 }, .max = { .i = 0x3f }, .step = { .f = 1./0x3f } }, -}, -.parm_gran = {}, -.ctcss_list = kenwood42_ctcss_list, -.dcs_list = common_dcs_list, -.preamp = { RIG_DBLST_END, }, -.attenuator = { RIG_DBLST_END, }, -.max_rit = Hz(0), -.max_xit = Hz(0), -.max_ifshift = Hz(0), -.vfo_ops = TMD710_VFO_OP, -.scan_ops = RIG_SCAN_VFO, -.targetable_vfo = RIG_TARGETABLE_NONE, -.transceive = RIG_TRN_RIG, -.bank_qty = 0, -.chan_desc_sz = 8, - -.chan_list = { - { 1, 199, RIG_MTYPE_MEM , {TMD710_CHANNEL_CAPS}}, /* normal MEM */ - { 200,219, RIG_MTYPE_EDGE , {TMD710_CHANNEL_CAPS}}, /* U/L MEM */ - { 221,222, RIG_MTYPE_CALL, {TMD710_CHANNEL_CAPS_WO_LO}}, /* Call 0/1 */ - RIG_CHAN_END, - }, -/* - * TODO: Japan & TM-D700S, and Taiwan models - */ -.rx_range_list1 = { - {MHz(118),MHz(470),TMD710_MODES,-1,-1,RIG_VFO_A}, - {MHz(136),MHz(174),TMD710_MODES_FM,-1,-1,RIG_VFO_B}, - {MHz(300),MHz(524),TMD710_MODES_FM,-1,-1,RIG_VFO_B}, - {MHz(800),MHz(1300),TMD710_MODES_FM,-1,-1,RIG_VFO_B}, - RIG_FRNG_END, - }, /* rx range */ -.tx_range_list1 = { - {MHz(144),MHz(146),TMD710_MODES_TX,W(5),W(50),RIG_VFO_A}, - {MHz(430),MHz(440),TMD710_MODES_TX,W(5),W(35),RIG_VFO_A}, - RIG_FRNG_END, - }, /* tx range */ - -.rx_range_list2 = { - {MHz(118),MHz(470),TMD710_MODES,-1,-1,RIG_VFO_A}, - {MHz(136),MHz(174),TMD710_MODES_FM,-1,-1,RIG_VFO_B}, - {MHz(300),MHz(524),TMD710_MODES_FM,-1,-1,RIG_VFO_B}, - {MHz(800),MHz(1300),TMD710_MODES_FM,-1,-1,RIG_VFO_B}, /* TODO: cellular blocked */ - RIG_FRNG_END, - }, /* rx range */ -.tx_range_list2 = { - {MHz(144),MHz(148),TMD710_MODES_TX,W(5),W(50),RIG_VFO_A}, - {MHz(430),MHz(450),TMD710_MODES_TX,W(5),W(35),RIG_VFO_A}, - RIG_FRNG_END, - }, /* tx range */ - -.tuning_steps = { - {TMD710_MODES,kHz(5)}, - {TMD710_MODES,kHz(6.25)}, - {TMD710_MODES,kHz(8.33)}, - {TMD710_MODES,kHz(10)}, - {TMD710_MODES,kHz(12.5)}, - {TMD710_MODES,kHz(15)}, - {TMD710_MODES,kHz(20)}, - {TMD710_MODES,kHz(25)}, - {TMD710_MODES,kHz(30)}, - {TMD710_MODES,kHz(50)}, - {TMD710_MODES,kHz(100)}, - RIG_TS_END, - }, - /* mode/filter list, remember: order matters! */ -//.filters = { -// {RIG_MODE_FM, kHz(12)}, -// {RIG_MODE_AM, kHz(9)}, /* TBC */ -// RIG_FLT_END, -// }, -.priv = (void *)&tmd710_priv_caps, - -.rig_init = kenwood_init, -.rig_cleanup = kenwood_cleanup, -.set_freq = tmd710_set_freq, -.get_freq = tmd710_get_freq, -.set_mode = tmd710_set_mode, -.get_mode = tmd710_get_mode, -.set_vfo = tmd710_set_vfo, -.get_vfo = tmd710_get_vfo, -.set_ts = tmd710_set_ts, -.get_ts = tmd710_get_ts, -.set_ctcss_tone = tmd710_set_ctcss_tone, -.get_ctcss_tone = tmd710_get_ctcss_tone, -.set_ctcss_sql = tmd710_set_ctcss_sql, -.get_ctcss_sql = tmd710_get_ctcss_sql, -//.set_split_vfo = th_set_split_vfo, -//.get_split_vfo = th_get_split_vfo, -.set_dcs_sql = tmd710_set_dcs_sql, -.get_dcs_sql = tmd710_get_dcs_sql, -.set_mem = tmd710_set_mem, -.get_mem = tmd710_get_mem, -//.set_channel = tmd710_set_channel, -.get_channel = tmd710_get_channel, -//.set_trn = th_set_trn, -//.get_trn = th_get_trn, - -//.set_func = th_set_func, -//.get_func = th_get_func, -//.set_level = th_set_level, -//.get_level = th_get_level, -//.set_parm = th_set_parm, -//.get_parm = th_get_parm, -//.get_info = th_get_info, -//.get_dcd = th_get_dcd, -//.set_ptt = th_set_ptt, -//.vfo_op = th_vfo_op, -//.scan = th_scan, - -.set_rptr_shift = tmd710_set_rptr_shift, -.get_rptr_shift = tmd710_get_rptr_shift, -.set_rptr_offs = tmd710_set_rptr_offs, -.get_rptr_offs = tmd710_get_rptr_offs, - -.decode_event = th_decode_event, +const struct confparams tmd710_ext_levels[] = { + { TOK_LEVEL_EXT_DATA_BAND, "EXTDATABAND", "External data band", "External data band", + NULL, RIG_CONF_COMBO, { .c = { .combostr = { "A", "B", "TXA-RXB", "TXB-RXA", NULL } } } + }, + { RIG_CONF_END, NULL, } }; -/* structure for handling fo/me radio command */ +const struct rig_caps tmd710_caps = { + .rig_model = RIG_MODEL_TMD710, + .model_name = "TM-D710(G)", + .mfg_name = "Kenwood", + .version = BACKEND_VER ".1", + .copyright = "LGPL", + .status = RIG_STATUS_BETA, + .rig_type = RIG_TYPE_MOBILE | RIG_FLAG_APRS | RIG_FLAG_TNC, + .ptt_type = RIG_PTT_RIG, + .dcd_type = RIG_DCD_RIG, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 9600, + .serial_rate_max = 57600, + .serial_data_bits = 8, + .serial_stop_bits = 1, + .serial_parity = RIG_PARITY_NONE, + .serial_handshake = RIG_HANDSHAKE_NONE, + .write_delay = 0, + .post_write_delay = 0, + .timeout = 1000, + .retry = 3, + + .has_get_func = TMD710_FUNC_GET, + .has_set_func = TMD710_FUNC_SET, + .has_get_level = TMD710_LEVEL_ALL, + .has_set_level = RIG_LEVEL_SET(TMD710_LEVEL_ALL), + .has_get_parm = TMD710_PARMS, + .has_set_parm = TMD710_PARMS, + .level_gran = {}, + .parm_gran = {}, + .ctcss_list = kenwood42_ctcss_list, + .dcs_list = common_dcs_list, + .preamp = {RIG_DBLST_END,}, + .attenuator = {RIG_DBLST_END,}, + .max_rit = Hz(0), + .max_xit = Hz(0), + .max_ifshift = Hz(0), + .vfo_ops = TMD710_VFO_OP, + .scan_ops = RIG_SCAN_NONE, + .targetable_vfo = RIG_TARGETABLE_NONE, + .transceive = RIG_TRN_OFF, + .bank_qty = 0, + .chan_desc_sz = 8, + + .chan_list = { + {0, 199, RIG_MTYPE_MEM, {TMD710_CHANNEL_CAPS}}, /* normal MEM */ + {200, 219, RIG_MTYPE_EDGE, {TMD710_CHANNEL_CAPS}}, /* U/L MEM */ + {221, 222, RIG_MTYPE_CALL, {TMD710_CHANNEL_CAPS_WO_LO}}, /* Call 0/1 */ + RIG_CHAN_END, + }, + /* + * TODO: Japan & TM-D700S, and Taiwan models + */ + .rx_range_list1 = { + {MHz(118), MHz(470), TMD710_MODES, -1, -1, RIG_VFO_A | RIG_VFO_MEM}, + {MHz(136), MHz(174), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, + {MHz(300), MHz(524), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, + {MHz(800), MHz(1300), TMD710_MODES_FM, -1, -1, RIG_VFO_B | RIG_VFO_MEM}, + RIG_FRNG_END, + }, /* rx range */ + .tx_range_list1 = { + {MHz(144), MHz(146), TMD710_MODES_TX, W(5), W(50), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, + {MHz(430), MHz(440), TMD710_MODES_TX, W(5), W(35), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, + RIG_FRNG_END, + }, /* tx range */ + + .rx_range_list2 = { + {MHz(118), MHz(470), TMD710_MODES, -1, -1, RIG_VFO_A | RIG_VFO_MEM}, + {MHz(136), MHz(174), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, + {MHz(300), MHz(524), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, + {MHz(800), MHz(1300), TMD710_MODES_FM, -1, -1, RIG_VFO_B | RIG_VFO_MEM}, /* TODO: cellular blocked */ + RIG_FRNG_END, + }, /* rx range */ + .tx_range_list2 = { + {MHz(144), MHz(148), TMD710_MODES_TX, W(5), W(50), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, + {MHz(430), MHz(450), TMD710_MODES_TX, W(5), W(35), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, + RIG_FRNG_END, + }, /* tx range */ + + .tuning_steps = { + {TMD710_MODES, kHz(5)}, + {TMD710_MODES, kHz(6.25)}, + {TMD710_MODES, kHz(8.33)}, + {TMD710_MODES, kHz(10)}, + {TMD710_MODES, kHz(12.5)}, + {TMD710_MODES, kHz(15)}, + {TMD710_MODES, kHz(20)}, + {TMD710_MODES, kHz(25)}, + {TMD710_MODES, kHz(30)}, + {TMD710_MODES, kHz(50)}, + {TMD710_MODES, kHz(100)}, + RIG_TS_END, + }, + /* mode/filter list, remember: order matters! */ + .filters = { + {RIG_MODE_FM, kHz(15)}, + {RIG_MODE_FMN, kHz(5)}, + {RIG_MODE_AM, kHz(4)}, + RIG_FLT_END, + }, + .priv = (void *) &tmd710_priv_caps, + + .rig_init = kenwood_init, + .rig_cleanup = kenwood_cleanup, + .set_freq = tmd710_set_freq, + .get_freq = tmd710_get_freq, + .set_mode = tmd710_set_mode, + .get_mode = tmd710_get_mode, + .set_vfo = tmd710_set_vfo, + .get_vfo = tmd710_get_vfo, + .set_ts = tmd710_set_ts, + .get_ts = tmd710_get_ts, + .set_ctcss_tone = tmd710_set_ctcss_tone, + .get_ctcss_tone = tmd710_get_ctcss_tone, + .set_ctcss_sql = tmd710_set_ctcss_sql, + .get_ctcss_sql = tmd710_get_ctcss_sql, + //.set_split_vfo = th_set_split_vfo, + //.get_split_vfo = th_get_split_vfo, + .set_dcs_sql = tmd710_set_dcs_sql, + .get_dcs_sql = tmd710_get_dcs_sql, + .set_mem = tmd710_set_mem, + .get_mem = tmd710_get_mem, + .set_channel = tmd710_set_channel, + .get_channel = tmd710_get_channel, + //.set_trn = th_set_trn, + //.get_trn = th_get_trn, + + .set_func = tmd710_set_func, + .get_func = tmd710_get_func, + .set_level = tmd710_set_level, + .get_level = tmd710_get_level, + .set_parm = tmd710_set_parm, + .get_parm = tmd710_get_parm, + //.get_info = th_get_info, + .get_dcd = tmd710_get_dcd, + .set_ptt = tmd710_set_ptt, + .vfo_op = tmd710_vfo_op, + //.scan = th_scan, + .set_ext_level = tmd710_set_ext_level, + .get_ext_level = tmd710_get_ext_level, + + .extlevels = tmd710_ext_levels, + + .set_rptr_shift = tmd710_set_rptr_shift, + .get_rptr_shift = tmd710_get_rptr_shift, + .set_rptr_offs = tmd710_set_rptr_offs, + .get_rptr_offs = tmd710_get_rptr_offs, + + .decode_event = th_decode_event, +}; + +/* structure for handling FO radio command */ typedef struct { - int vfo; // P1 or mem channel + int vfo; // P1 freq_t freq; // P2 int step; // P3 int shift; // P4 @@ -291,407 +406,763 @@ typedef struct { int mode; // P13 } tmd710_fo; -/* the d710 has a single command ME that queries and sets many values */ -/* this pulls that string from the radio given a memory channel */ -/* push/pull language is uses for stuff inside 710 driver rather than get/set */ -/* uses same structure as FO command */ -/* there are two extra unknown fields ignored until kenwood confirms what they are*/ -int -tmd710_pull_me(RIG * rig,int ch, tmd710_fo *fo_struct) { +/* structure for handling ME radio command */ +typedef struct { + int channel; // P1 + freq_t freq; // P2 + int step; // P3 + int shift; // P4 + int reverse; // P5 + int tone; // P6 + int ct; // P7 + int dcs; // P8 + int tone_freq; // P9 + int ct_freq; // P10 + int dcs_val; // P11 + int offset; // P12 + int mode; // P13 + freq_t tx_freq; // P14 + int p15_unknown; // P15 + int lockout; // P16 +} tmd710_me; + +/* structure for handling MU (menu) radio command */ +typedef struct { + int beep; // P1 0/1 + int beep_volume; // P2 (1-7) + int ext_speaker_mode; // P3 + int announce; // P4 + int language; // P5 + int voice_volume; // P6 (0-7) + int voice_speed; // P7 (0-4) + int playback_repeat; // P8 0/1 + int playback_repeat_interval; // P9 (00-60) + int continuous_recording; // P10 0/1 + int vhf_aip; // P11 0/1 + int uhf_aip; // P12 0/1 + int smeter_sql_hang_up_time; // P13 + int mute_hang_up_time; // P14 + int beat_shift; // P15 0/1 + int timeout_timer; // P16 + int recall_method; // P17 + int echolink_speed; // P18 + int dtmf_hold; // P19 0/1 + int dtmf_speed; // P20 + int dtmf_pause; // P21 + int dtmf_key_lock; // P22 0/1 + int auto_repeater_offset; // P23 0/1 + int tone_1750_tx_hold; // P24 0/1 + int p25_unknown; // TODO + int brightness_level; // P26 (0-8) + int auto_brightness; // P27 0/1 + int backlight_color; // P28 + int pf1_key; // P29 + int pf2_key; // P30 + int mic_pf1_key; // P31 + int mic_pf2_key; // P32 + int mic_pf3_key; // P33 + int mic_pf4_key; // P34 + int mic_key_lock; // P35 0/1 + int scan_resume; // P36 + int auto_power_off; // P37 + int ext_data_band; // P38 + int ext_data_speed; // P39 + int sqc_source; // P40 + int auto_pm_store; // P41 0/1 + int display_partition_bar; // P42 0/1 +} tmd710_mu; + +static int tmd710_get_vfo_num(RIG *rig, int *vfonum, vfo_t *vfo) { + char buf[10]; + int retval, ctrlnum, pttnum; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + retval = kenwood_transaction(rig, "BC", buf, sizeof(buf)); + if (retval != RIG_OK) { + return retval; + } + + retval = sscanf(buf, "BC %d,%d", &ctrlnum, &pttnum); + if (retval != 2) { + rig_debug(RIG_DEBUG_ERR, "Unable to parse '%s', expected 'BC c,p'\n", buf); + return -RIG_EPROTO; + } + + switch (ctrlnum) { + case TMD710_BAND_A: + if (vfo != NULL) { + *vfo = RIG_VFO_A; + } + break; + case TMD710_BAND_B: + if (vfo != NULL) { + *vfo = RIG_VFO_B; + } + break; + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, buf[3]); + return -RIG_EVFO; + } + + if (vfonum != NULL) { + *vfonum = ctrlnum; + } + + return RIG_OK; +} + +static int tmd710_get_vfo_and_mode(RIG *rig, vfo_t *vfo, int *vfomode) +{ + char cmdbuf[10], buf[10]; + int retval, vfonum, vfomodenum; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + /* Get VFO band */ + + retval = tmd710_get_vfo_num(rig, &vfonum, vfo); + if (retval != RIG_OK) { + return retval; + } + + /* Get mode of the VFO band */ + + snprintf(cmdbuf, sizeof(cmdbuf), "VM %d", vfonum); + + retval = kenwood_safe_transaction(rig, cmdbuf, buf, 10, 6); + if (retval != RIG_OK) { + return retval; + } + + retval = sscanf(buf, "VM %d,%d", &vfonum, &vfomodenum); + if (retval != 2) { + rig_debug(RIG_DEBUG_ERR, "Unable to parse '%s', expected 'VM c,m'\n", buf); + return -RIG_EPROTO; + } + + if (vfomode != NULL) { + *vfomode = vfomodenum; + } + + return RIG_OK; +} + +static int tmd710_resolve_vfo(RIG *rig, vfo_t vfo, vfo_t *resolved_vfo, int *resolved_vfonum) +{ + switch (vfo) { + case RIG_VFO_CURR: + return tmd710_get_vfo_num(rig, resolved_vfonum, resolved_vfo); + case RIG_VFO_A: + if (resolved_vfo != NULL) { + *resolved_vfo = RIG_VFO_A; + } + if (resolved_vfonum != NULL) { + *resolved_vfonum = TMD710_BAND_A; + } + break; + case RIG_VFO_B: + if (resolved_vfo != NULL) { + *resolved_vfo = RIG_VFO_B; + } + if (resolved_vfonum != NULL) { + *resolved_vfonum = TMD710_BAND_B; + } + break; + default: + return -RIG_ENTARGET; + } + + return RIG_OK; +} + +static int tmd710_scan_me(char *buf, tmd710_me *me_struct) { + int retval; + + retval = num_sscanf(buf, "ME %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d,%"SCNfreq",%d,%d", + &me_struct->channel, &me_struct->freq, + &me_struct->step, &me_struct->shift, + &me_struct->reverse, &me_struct->tone, + &me_struct->ct, &me_struct->dcs, + &me_struct->tone_freq, &me_struct->ct_freq, + &me_struct->dcs_val, &me_struct->offset, + &me_struct->mode, &me_struct->tx_freq, + &me_struct->p15_unknown, &me_struct->lockout); + + if (retval != 16) { + rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); + return -RIG_ERJCTED; + } + + return RIG_OK; +} + +/* + * The TM-D710(G) has a single command ME that queries and sets many values. + * This function pulls that string from the radio given a memory channel. + * Push/pull naming is used inside the backend rather than get/set. + * There is one unknown field. + */ +int tmd710_pull_me(RIG *rig, int ch, tmd710_me *me_struct) +{ char cmdbuf[8]; - char buf[76]; + char buf[80]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - snprintf(cmdbuf,sizeof(cmdbuf),"ME %d",ch); - retval = kenwood_safe_transaction(rig, cmdbuf, buf, sizeof(buf), 64); - if (retval != RIG_OK) + snprintf(cmdbuf, sizeof(cmdbuf), "ME %03d", ch); + retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); + if (retval != RIG_OK) { return retval; + } - retval = num_sscanf(buf, "ME %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d", - &fo_struct->vfo, &fo_struct->freq, - &fo_struct->step, &fo_struct->shift, - &fo_struct->reverse, &fo_struct->tone, - &fo_struct->ct, &fo_struct->dcs, - &fo_struct->tone_freq, &fo_struct->ct_freq, - &fo_struct->dcs_val, &fo_struct->offset, - &fo_struct->mode); + retval = tmd710_scan_me(buf, me_struct); + if (retval != RIG_OK) { + return retval; + } + + return RIG_OK; +} + +int tmd710_push_me(RIG *rig, tmd710_me *me_struct) +{ + char cmdbuf[80]; + char buf[80]; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + snprintf(cmdbuf, sizeof(cmdbuf), "ME %03d,%010.0f,%1d,%1d,%1d,%1d,%1d,%1d,%02d,%02d,%03d,%08d,%1d,%010.0f,%1d,%1d", + me_struct->channel, me_struct->freq, + me_struct->step, me_struct->shift, + me_struct->reverse, me_struct->tone, + me_struct->ct, me_struct->dcs, + me_struct->tone_freq, me_struct->ct_freq, + me_struct->dcs_val, me_struct->offset, + me_struct->mode, me_struct->tx_freq, + me_struct->p15_unknown, me_struct->lockout); + + return kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); +} + +int tmd710_get_memory_name(RIG *rig, int ch, char *name) +{ + char cmdbuf[8]; + char buf[80]; + int retval; + + rig_debug(RIG_DEBUG_TRACE, "%s: called on channel %d\n", __func__, ch); + + snprintf(cmdbuf, sizeof(cmdbuf), "MN %03d", ch); + retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); + if (retval != RIG_OK) { + return retval; + } + + retval = num_sscanf(buf, "MN %d,%s", &ch, name); + if (retval != 2) { + rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); + return -RIG_ERJCTED; + } + + return RIG_OK; +} + +int tmd710_set_memory_name(RIG *rig, int ch, char *name) +{ + char cmdbuf[32]; + char buf[80]; + int retval; + + rig_debug(RIG_DEBUG_TRACE, "%s: called on channel %d with name %s\n", __func__, ch, name); + + snprintf(cmdbuf, sizeof(cmdbuf), "MN %03d,%s", ch, name); + retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); + if (retval != RIG_OK) { + return retval; + } + + return RIG_OK; +} + +/* + * The TM-D710(G) has a single command FO that queries and sets many values. + * This function pulls that string from the radio given a VFO. + * Push/pull language is used inside the backend rather than get/set. + */ +int tmd710_pull_fo(RIG *rig, vfo_t vfo, tmd710_fo *fo_struct) +{ + char cmdbuf[8]; + char buf[80]; + int vfonum; + int retval; + + rig_debug(RIG_DEBUG_TRACE, "%s: called with VFO %08X\n", __func__, vfo); + + retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); + if (retval != RIG_OK) { + return retval; + } + + snprintf(cmdbuf, sizeof(cmdbuf), "FO %1d", vfonum); + retval = kenwood_safe_transaction(rig, cmdbuf, buf, sizeof(buf), 48); + if (retval != RIG_OK) { + return retval; + } + + retval = num_sscanf(buf, "FO %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d", + &fo_struct->vfo, &fo_struct->freq, + &fo_struct->step, &fo_struct->shift, + &fo_struct->reverse, &fo_struct->tone, + &fo_struct->ct, &fo_struct->dcs, + &fo_struct->tone_freq, &fo_struct->ct_freq, + &fo_struct->dcs_val, &fo_struct->offset, + &fo_struct->mode); if (retval != 13) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } + return RIG_OK; } -int -tmd710_push_me(RIG * rig,vfo_t vfo, tmd710_fo *fo_struct) { - char cmdbuf[50]; - char buf[50]; - int retval; +int tmd710_push_fo(RIG *rig, vfo_t vfo, tmd710_fo *fo_struct) +{ + char cmdbuf[80]; + char buf[80]; + int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - // table is zero-based, tmd710 is 1-based - ++fo_struct->tone_freq; + snprintf(cmdbuf, sizeof(cmdbuf), "FO %1d,%010.0f,%1d,%1d,%1d,%1d,%1d,%1d,%02d,%02d,%03d,%08d,%1d", + fo_struct->vfo, fo_struct->freq, + fo_struct->step, fo_struct->shift, + fo_struct->reverse, fo_struct->tone, + fo_struct->ct, fo_struct->dcs, + fo_struct->tone_freq, fo_struct->ct_freq, + fo_struct->dcs_val, fo_struct->offset, + fo_struct->mode); + + retval = kenwood_safe_transaction(rig, cmdbuf, buf, sizeof(buf), 48); + if (retval != RIG_OK) { + return retval; + } + + retval = num_sscanf(buf, "FO %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d", + &fo_struct->vfo, &fo_struct->freq, + &fo_struct->step, &fo_struct->shift, + &fo_struct->reverse, &fo_struct->tone, + &fo_struct->ct, &fo_struct->dcs, + &fo_struct->tone_freq, &fo_struct->ct_freq, + &fo_struct->dcs_val, &fo_struct->offset, + &fo_struct->mode); + if (retval != 13) { + rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); + return -RIG_ERJCTED; + } + + return RIG_OK; +} + +int tmd710_scan_mu(char *buf, tmd710_mu *mu_struct) { + int retval; + + retval = num_sscanf(buf, + "MU %d,%d,%d,%d,%d,%d,%d,%d,%d,%d," + "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d," + "%d,%d,%d,%d,%d,%d,%d,%d,%X,%X," + "%X,%X,%X,%X,%d,%d,%d,%d,%d,%d," + "%d,%d", + &mu_struct->beep, + &mu_struct->beep_volume, + &mu_struct->ext_speaker_mode, + &mu_struct->announce, + &mu_struct->language, + &mu_struct->voice_volume, + &mu_struct->voice_speed, + &mu_struct->playback_repeat, + &mu_struct->playback_repeat_interval, + &mu_struct->continuous_recording, + &mu_struct->vhf_aip, + &mu_struct->uhf_aip, + &mu_struct->smeter_sql_hang_up_time, + &mu_struct->mute_hang_up_time, + &mu_struct->beat_shift, + &mu_struct->timeout_timer, + &mu_struct->recall_method, + &mu_struct->echolink_speed, + &mu_struct->dtmf_hold, + &mu_struct->dtmf_speed, + &mu_struct->dtmf_pause, + &mu_struct->dtmf_key_lock, + &mu_struct->auto_repeater_offset, + &mu_struct->tone_1750_tx_hold, + &mu_struct->p25_unknown, + &mu_struct->brightness_level, + &mu_struct->auto_brightness, + &mu_struct->backlight_color, + &mu_struct->pf1_key, + &mu_struct->pf2_key, + &mu_struct->mic_pf1_key, + &mu_struct->mic_pf2_key, + &mu_struct->mic_pf3_key, + &mu_struct->mic_pf4_key, + &mu_struct->mic_key_lock, + &mu_struct->scan_resume, + &mu_struct->auto_power_off, + &mu_struct->ext_data_band, + &mu_struct->ext_data_speed, + &mu_struct->sqc_source, + &mu_struct->auto_pm_store, + &mu_struct->display_partition_bar + ); + + if (retval != 42) { + rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); + return -RIG_ERJCTED; + } + + return RIG_OK; +} + +int tmd710_pull_mu(RIG *rig, tmd710_mu *mu_struct) +{ + char buf[128]; + int retval; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + retval = kenwood_transaction(rig, "MU", buf, sizeof(buf)); + if (retval != RIG_OK) { + return retval; + } + + retval = tmd710_scan_mu(buf, mu_struct); + if (retval != RIG_OK) { + return retval; + } + + return RIG_OK; +} + +int tmd710_push_mu(RIG *rig, tmd710_mu *mu_struct) +{ + char cmdbuf[128]; + char buf[128]; + int retval; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); // we re-use fo_struct->vfo for the channel# - snprintf(cmdbuf,49,"ME %031d,%010.0f,%1d,%1d,%1d,%1d,%1d,%1d,%02d,%02d,%03d,%08d,%1d", - fo_struct->vfo, fo_struct->freq, - fo_struct->step, fo_struct->shift, - fo_struct->reverse, fo_struct->tone, - fo_struct->ct, fo_struct->dcs, - fo_struct->tone_freq, fo_struct->ct_freq, - fo_struct->dcs_val, fo_struct->offset, - fo_struct->mode); + snprintf(cmdbuf, sizeof(cmdbuf), + "MU %1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%02d,%1d," + "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d," + "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%02X,%02X," + "%02X,%02X,%02X,%02X,%1d,%1d,%1d,%1d,%1d,%1d," + "%1d,%1d", + mu_struct->beep, + mu_struct->beep_volume, + mu_struct->ext_speaker_mode, + mu_struct->announce, + mu_struct->language, + mu_struct->voice_volume, + mu_struct->voice_speed, + mu_struct->playback_repeat, + mu_struct->playback_repeat_interval, + mu_struct->continuous_recording, + mu_struct->vhf_aip, + mu_struct->uhf_aip, + mu_struct->smeter_sql_hang_up_time, + mu_struct->mute_hang_up_time, + mu_struct->beat_shift, + mu_struct->timeout_timer, + mu_struct->recall_method, + mu_struct->echolink_speed, + mu_struct->dtmf_hold, + mu_struct->dtmf_speed, + mu_struct->dtmf_pause, + mu_struct->dtmf_key_lock, + mu_struct->auto_repeater_offset, + mu_struct->tone_1750_tx_hold, + mu_struct->p25_unknown, + mu_struct->brightness_level, + mu_struct->auto_brightness, + mu_struct->backlight_color, + mu_struct->pf1_key, + mu_struct->pf2_key, + mu_struct->mic_pf1_key, + mu_struct->mic_pf2_key, + mu_struct->mic_pf3_key, + mu_struct->mic_pf4_key, + mu_struct->mic_key_lock, + mu_struct->scan_resume, + mu_struct->auto_power_off, + mu_struct->ext_data_band, + mu_struct->ext_data_speed, + mu_struct->sqc_source, + mu_struct->auto_pm_store, + mu_struct->display_partition_bar + ); - retval = kenwood_safe_transaction(rig, cmdbuf, buf, sizeof(buf), 48); - if (retval != RIG_OK) + retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); + if (retval != RIG_OK) { + return retval; + } + + retval = tmd710_scan_mu(buf, mu_struct); + if (retval != RIG_OK) { return retval; - - retval = num_sscanf(buf, "ME %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d", - &fo_struct->vfo, &fo_struct->freq, - &fo_struct->step, &fo_struct->shift, - &fo_struct->reverse, &fo_struct->tone, - &fo_struct->ct, &fo_struct->dcs, - &fo_struct->tone_freq, &fo_struct->ct_freq, - &fo_struct->dcs_val, &fo_struct->offset, - &fo_struct->mode); - if (retval != 13) { - rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); - return -RIG_ERJCTED; } - // table is zero-based, tmd710 is 1-based - --fo_struct->tone_freq; return RIG_OK; - -} - -/* the d710 has a single command FO that queries and sets many values */ -/* this pulls that string from the radio given a vfo */ -/* push/pull language is uses for stuff inside 710 driver rather than get/set */ -int -tmd710_pull_fo(RIG * rig,vfo_t vfo, tmd710_fo *fo_struct) { - char cmdbuf[8]; - char buf[64]; - int vfonum = 0; - int retval; - - rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - - switch (vfo) { - case (RIG_VFO_CURR): - vfonum = rig->state.current_vfo==RIG_VFO_B; - break; - case (RIG_VFO_A): - vfonum = 0; - break; - case (RIG_VFO_B): - vfonum = 1; - break; - - } - - snprintf(cmdbuf,sizeof(cmdbuf),"FO %d",vfonum); - retval = kenwood_safe_transaction(rig, cmdbuf, buf, sizeof(buf), 48); - if (retval != RIG_OK) - return retval; - - retval = num_sscanf(buf, "FO %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d", - &fo_struct->vfo, &fo_struct->freq, - &fo_struct->step, &fo_struct->shift, - &fo_struct->reverse, &fo_struct->tone, - &fo_struct->ct, &fo_struct->dcs, - &fo_struct->tone_freq, &fo_struct->ct_freq, - &fo_struct->dcs_val, &fo_struct->offset, - &fo_struct->mode); - if (retval != 13) { - rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); - return -RIG_ERJCTED; - } - // table is zero-based, tmd710 is 1-based - --fo_struct->tone_freq; - - return RIG_OK; -} - -int -tmd710_push_fo(RIG * rig,vfo_t vfo, tmd710_fo *fo_struct) { - char cmdbuf[50]; - char buf[50]; - int retval; - - rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - - // table is zero-based, tmd710 is 1-based - ++fo_struct->tone_freq; - - snprintf(cmdbuf,49,"FO %1d,%010.0f,%1d,%1d,%1d,%1d,%1d,%1d,%02d,%02d,%03d,%08d,%1d", - fo_struct->vfo, fo_struct->freq, - fo_struct->step, fo_struct->shift, - fo_struct->reverse, fo_struct->tone, - fo_struct->ct, fo_struct->dcs, - fo_struct->tone_freq, fo_struct->ct_freq, - fo_struct->dcs_val, fo_struct->offset, - fo_struct->mode); - - retval = kenwood_safe_transaction(rig, cmdbuf, buf, sizeof(buf), 48); - if (retval != RIG_OK) - return retval; - - retval = num_sscanf(buf, "FO %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d", - &fo_struct->vfo, &fo_struct->freq, - &fo_struct->step, &fo_struct->shift, - &fo_struct->reverse, &fo_struct->tone, - &fo_struct->ct, &fo_struct->dcs, - &fo_struct->tone_freq, &fo_struct->ct_freq, - &fo_struct->dcs_val, &fo_struct->offset, - &fo_struct->mode); - if (retval != 13) { - rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); - return -RIG_ERJCTED; - } - // table is zero-based, tmd710 is 1-based - --fo_struct->tone_freq; - - return RIG_OK; - } /* - * th_set_freq + * tmd710_set_freq * Assumes rig!=NULL */ -int -tmd710_set_freq(RIG *rig, vfo_t vfo, freq_t freq) +int tmd710_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; tmd710_fo fo_struct; - long freq5,freq625,freq_sent; + long freq5, freq625, freq_sent; int step; - + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - - // if (vfo != RIG_VFO_CURR && vfo != rig->state.current_vfo) - // return kenwood_wrong_vfo(__func__, vfo); - - retval = tmd710_pull_fo (rig,vfo,&fo_struct); - if (retval != RIG_OK){ - return retval; + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; } - freq5=round(freq/5000)*5000; - freq625=round(freq/6250)*6250; - if (fabs(freq5-freq)= MHz(470) ? 4 : step; - fo_struct.freq = freq_sent >= MHz(470) ? (round(freq_sent/10000)*10000) : freq_sent; - - retval=tmd710_push_fo (rig, vfo, &fo_struct); - - return retval; + fo_struct.freq = freq_sent >= MHz(470) ? (round(freq_sent / 10000) * 10000) : freq_sent; + + return tmd710_push_fo(rig, vfo, &fo_struct); } /* - * th_get_freq + * tmd710_get_freq * Assumes rig!=NULL, freq!=NULL */ -int -tmd710_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) +int tmd710_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { tmd710_fo fo_struct; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - //if (vfo != RIG_VFO_CURR && vfo != rig->state.current_vfo) - // return kenwood_wrong_vfo(__func__, vfo); - - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - - *freq = fo_struct.freq;; + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval == RIG_OK) { + *freq = fo_struct.freq; + } return retval; } +static int tmd710_find_ctcss_index(RIG *rig, tone_t tone, int *ctcss_index) { + int k, stepind = -1; + for (k = 0; k < 42; k++) { + if (rig->caps->ctcss_list[k] == tone) { + stepind = k; + break; + } + } + if (stepind == -1) { + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported tone value '%d'\n", __func__, tone); + return -RIG_EINVAL; + } + + *ctcss_index = stepind; + + return RIG_OK; +} + /* * tmd710_set_ctcss_tone * Assumes rig!=NULL, freq!=NULL */ -static int -tmd710_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) +static int tmd710_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { - int retval,k,stepind = -1; + int retval, stepind; tmd710_fo fo_struct; + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - for (k=0;k<42;k++) { - if (rig->caps->ctcss_list[k]==tone) { - stepind = k; - break; - } + + retval = tmd710_find_ctcss_index(rig, tone, &stepind); + if (retval != RIG_OK) { + return retval; } - if (stepind == -1) { - rig_debug(RIG_DEBUG_ERR, "%s: Unsupported tone value '%d'\n", __func__, tone); - return -RIG_EINVAL; + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; } - - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - if (retval == RIG_OK) { - fo_struct.tone_freq = stepind; - - retval = tmd710_push_fo(rig,vfo,&fo_struct); - } - return retval; + + fo_struct.tone_freq = stepind; + + return tmd710_push_fo(rig, vfo, &fo_struct); } - - /* * tmd710_get_ctcss_tone * Assumes rig!=NULL, freq!=NULL */ -int -tmd710_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) +int tmd710_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { tmd710_fo fo_struct; int retval; - + const struct rig_caps *caps; caps = rig->caps; - - + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - //if (vfo != RIG_VFO_CURR && vfo != rig->state.current_vfo) - // return kenwood_wrong_vfo(__func__, vfo); + retval = tmd710_pull_fo(rig, vfo, &fo_struct); - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - if (retval == RIG_OK) { - *tone = caps->ctcss_list[fo_struct.tone_freq]; } - + return retval; } /* - * tmd710_set_ts + * tmd710_set_ctcss_sql * Assumes rig!=NULL, freq!=NULL */ -static int -tmd710_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) +static int tmd710_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { - int retval,k,stepind = -1; + int retval, stepind; tmd710_fo fo_struct; + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - for (k=0;k<42;k++) { - if (rig->caps->ctcss_list[k]==tone) { - stepind = k; - break; - } + + retval = tmd710_find_ctcss_index(rig, tone, &stepind); + if (retval != RIG_OK) { + return retval; } - if (stepind == -1) { - rig_debug(RIG_DEBUG_ERR, "%s: Unsupported tone value '%d'\n", __func__, tone); - return -RIG_EINVAL; + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; } - - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - if (retval == RIG_OK) { - fo_struct.ct_freq = stepind; - - retval = tmd710_push_fo(rig,vfo,&fo_struct); - } - return retval; + + fo_struct.ct_freq = stepind; + + return tmd710_push_fo(rig, vfo, &fo_struct); } - - /* * tmd710_get_ctcss_sql * Assumes rig!=NULL, freq!=NULL */ -int -tmd710_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) +int tmd710_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { tmd710_fo fo_struct; int retval; - + const struct rig_caps *caps; caps = rig->caps; - - + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - //if (vfo != RIG_VFO_CURR && vfo != rig->state.current_vfo) - // return kenwood_wrong_vfo(__func__, vfo); + retval = tmd710_pull_fo(rig, vfo, &fo_struct); - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - if (retval == RIG_OK) { - *tone = caps->ctcss_list[fo_struct.ct_freq]; } - + return retval; } /* - * tmd710_set_mode - * Assumes rig!=NULL, freq!=NULL + * status: ok, no vfo checks */ -static int -tmd710_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) +int tmd710_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { int retval; tmd710_fo fo_struct; - rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - if (retval == RIG_OK) { - if (mode == RIG_MODE_FM) { - fo_struct.mode = 0; - } else if (mode == RIG_MODE_FMN) { - fo_struct.mode = 1; - }else if (mode == RIG_MODE_AM) { - fo_struct.mode = 2; - } else { - rig_debug(RIG_DEBUG_ERR, "%s: Illegal value from radio '%ld'\n", __func__, mode); + + if (!rig || !code) { + return -RIG_EINVAL; + } + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; + } + + if (fo_struct.dcs) { + *code = common_dcs_list[fo_struct.dcs_val]; + } else { + *code = 0; + } + + return RIG_OK; +} + +static int tmd710_find_dcs_index(tone_t code, int *dcs_index) { + int i = 0; + + // we only allow exact matches here + while (code != common_dcs_list[i]) { + if (common_dcs_list[i] == 0) { return -RIG_EINVAL; } - retval = tmd710_push_fo(rig,vfo,&fo_struct); + i++; } - return retval; + + *dcs_index = i; + + return RIG_OK; } - /* - * tmd710_get_mode - * Assumes rig!=NULL, freq!=NULL + * status: ok, no vfo checks */ -int -tmd710_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) +int tmd710_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { + int retval, dcs_index, dcs_enable; tmd710_fo fo_struct; - int retval; - - rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - - if (retval == RIG_OK) { - switch (fo_struct.mode) { - case 0: + if (code == 0) { + dcs_index = 0; + dcs_enable = 0; + } else { + retval = tmd710_find_dcs_index(code, &dcs_index); + if (retval != RIG_OK) { + return retval; + } + dcs_enable = 1; + } + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; + } + + fo_struct.dcs = dcs_enable; + fo_struct.dcs_val = dcs_index; + + return tmd710_push_fo(rig, vfo, &fo_struct); +} + +static int tmd710_get_mode_hamlib_values(int tmd710_mode, rmode_t *mode, pbwidth_t *width) { + switch (tmd710_mode) { + case 0: *mode = RIG_MODE_FM; *width = 15000; break; @@ -704,116 +1175,190 @@ tmd710_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) *width = 4000; break; default: - rig_debug(RIG_DEBUG_ERR, "%s: Illegal value from radio '%ld'\n", __func__, mode); + rig_debug(RIG_DEBUG_ERR, "%s: Illegal value from radio '%ld'\n", __func__, tmd710_mode); return -RIG_EINVAL; - + } + + return RIG_OK; +} + +/* + * tmd710_get_mode + * Assumes rig!=NULL, freq!=NULL + */ +int tmd710_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) +{ + tmd710_fo fo_struct; + int retval; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; + } + + retval = tmd710_get_mode_hamlib_values(fo_struct.mode, mode, width); + if (retval != RIG_OK) { + return retval; + } + + return RIG_OK; +} + +static int tmd710_get_mode_tmd710_value(rmode_t mode, int *tmd710_mode) { + if (mode == RIG_MODE_FM) { + *tmd710_mode = 0; + } else if (mode == RIG_MODE_FMN) { + *tmd710_mode = 1; + } else if (mode == RIG_MODE_AM) { + *tmd710_mode = 2; + } else { + rig_debug(RIG_DEBUG_ERR, "%s: Illegal value from radio '%ld'\n", __func__, mode); + return -RIG_EINVAL; + } + + return RIG_OK; +} + +/* + * tmd710_set_mode + * Assumes rig!=NULL, freq!=NULL + */ +static int tmd710_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) +{ + int retval, tmd710_mode; + tmd710_fo fo_struct; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + retval = tmd710_get_mode_tmd710_value(mode, &tmd710_mode); + if (retval != RIG_OK) { + return retval; + } + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; + } + + fo_struct.mode = tmd710_mode; + + return tmd710_push_fo(rig, vfo, &fo_struct); +} + +static int tmd710_find_tuning_step_index(RIG *rig, shortfreq_t ts, int *step_index) { + int k, stepind = -1; + + for (k = 0; k < TSLSTSIZ; k++) { + if ((rig->caps->tuning_steps[k].modes == RIG_MODE_NONE) + && (rig->caps->tuning_steps[k].ts == 0)) + break; + else if (rig->caps->tuning_steps[k].ts == ts) { + stepind = k; + break; } } - - return retval; + if (stepind == -1) { + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported tuning step value '%ld'\n", __func__, ts); + return -RIG_EINVAL; + } + + *step_index = stepind; + + return RIG_OK; } /* * tmd710_set_ts * Assumes rig!=NULL, freq!=NULL */ -static int -tmd710_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) +static int tmd710_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { - int retval,k,stepind = -1; + int retval, stepind; tmd710_fo fo_struct; + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - for (k=0;kcaps->tuning_steps[k].modes==RIG_MODE_NONE) - && (rig->caps->tuning_steps[k].ts==0)) - break; - else if (rig->caps->tuning_steps[k].ts==ts) { - stepind = k; - break; - } + + retval = tmd710_find_tuning_step_index(rig, ts, &stepind); + if (retval != RIG_OK) { + return retval; } - if (stepind == -1) { - rig_debug(RIG_DEBUG_ERR, "%s: Unsupported step value '%ld'\n", __func__, ts); - return -RIG_EINVAL; + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; } - - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - if (retval == RIG_OK) { - fo_struct.step = stepind; - - retval = tmd710_push_fo(rig,vfo,&fo_struct); - } - return retval; + + fo_struct.step = stepind; + + return tmd710_push_fo(rig, vfo, &fo_struct); } /* * tmd710_get_ts * Assumes rig!=NULL, freq!=NULL */ -static int -tmd710_get_ts(RIG *rig, vfo_t vfo, shortfreq_t* ts) +static int tmd710_get_ts(RIG *rig, vfo_t vfo, shortfreq_t* ts) { int retval; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval == RIG_OK) { *ts = rig->caps->tuning_steps[fo_struct.step].ts; } + return retval; } -/* - * tmd710_get_rptr_shft - * Assumes rig!=NULL, freq!=NULL - */ -int -tmd710_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) -{ - int retval; - tmd710_fo fo_struct; - rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - - if (retval == RIG_OK) { - switch (shift) { +int tmd710_get_rptr_shift_tmd710_value(rptr_shift_t shift, int *tmd710_shift) { + switch (shift) { case RIG_RPT_SHIFT_NONE: - fo_struct.shift = 0; + *tmd710_shift = 0; break; case RIG_RPT_SHIFT_PLUS: - fo_struct.shift = 1; + *tmd710_shift = 1; break; case RIG_RPT_SHIFT_MINUS: - fo_struct.shift = 2; + *tmd710_shift = 2; break; default: - rig_debug(RIG_DEBUG_ERR, "%s: Unexpected shift value '%d'\n", __func__, fo_struct.shift); + rig_debug(RIG_DEBUG_ERR, "%s: Unexpected shift value '%d'\n", __func__, shift); return -RIG_EPROTO; - break; - } } - return retval; + + return RIG_OK; } - /* - * tmd710_get_rptr_shft + * tmd710_set_rptr_shift * Assumes rig!=NULL, freq!=NULL */ -int -tmd710_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t* shift) +int tmd710_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { int retval; tmd710_fo fo_struct; + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - - if (retval == RIG_OK) { - switch (fo_struct.shift) { + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; + } + + retval = tmd710_get_rptr_shift_tmd710_value(shift, &fo_struct.shift); + if (retval != RIG_OK) { + return retval; + } + + return tmd710_push_fo(rig, vfo, &fo_struct); +} + +int tmd710_get_rptr_shift_hamlib_value(int tmd710_shift, rptr_shift_t *shift) { + switch (tmd710_shift) { case 0: *shift = RIG_RPT_SHIFT_NONE; break; @@ -824,49 +1369,65 @@ tmd710_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t* shift) *shift = RIG_RPT_SHIFT_MINUS; break; default: - rig_debug(RIG_DEBUG_ERR, "%s: Unexpected shift value '%d'\n", __func__, fo_struct.shift); + rig_debug(RIG_DEBUG_ERR, "%s: Unexpected shift value '%d'\n", __func__, tmd710_shift); return -RIG_EPROTO; - break; - } } - return retval; + + return RIG_OK; } /* - * th_set_rptr_offs - * Assumes rig!=NULL + * tmd710_get_rptr_shft + * Assumes rig!=NULL, freq!=NULL */ -int -tmd710_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t freq) +int tmd710_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *shift) { int retval; tmd710_fo fo_struct; - long freq5,freq625,freq_sent; - + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - - // if (vfo != RIG_VFO_CURR && vfo != rig->state.current_vfo) - // return kenwood_wrong_vfo(__func__, vfo); - - retval = tmd710_pull_fo (rig,vfo,&fo_struct); - if (retval != RIG_OK){ - return retval; + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; } - freq5=round(freq/5000)*5000; - freq625=round(freq/6250)*6250; - if (abs((int)(freq5-freq))= MHz(470) ? (round(freq_sent/10000)*10000) : freq_sent; - - retval=tmd710_push_fo (rig, vfo, &fo_struct); - - return retval; + fo_struct.offset = freq_sent >= MHz(470) ? (round(freq_sent / 10000) * 10000) : freq_sent; + + return tmd710_push_fo(rig, vfo, &fo_struct); } @@ -875,19 +1436,15 @@ tmd710_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t freq) * tmd710_get_rptr_offs * Assumes rig!=NULL, freq!=NULL */ -int -tmd710_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) +int tmd710_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { tmd710_fo fo_struct; int retval; - - rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - - //if (vfo != RIG_VFO_CURR && vfo != rig->state.current_vfo) - // return kenwood_wrong_vfo(__func__, vfo); - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval == RIG_OK) *rptr_offs = fo_struct.offset; @@ -895,354 +1452,812 @@ tmd710_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) return retval; } - - -int -tmd710_get_vfo_char(RIG *rig, vfo_t *vfo, char *vfoch) -{ - char cmdbuf[10], buf[10], vfoc; - int retval; - - rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - - /* Get VFO band */ - - retval = kenwood_transaction(rig, "BC", buf, sizeof (buf)); - if (retval != RIG_OK) - return retval; - size_t length = strlen (buf); - switch (length) { - case 6: /*intended for D700 BC 0,0*/ - if ((buf[0]=='B') &&(buf[1]=='C') && (buf[2]==' ') && (buf[4]=',')){ - vfoc = buf[3]; - } else { - rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer format '%s'\n", __func__, buf); - return -RIG_EPROTO; - } - break; - default: - rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer length '%c'\n", __func__, length); - return -RIG_EPROTO; - break; - } - - - switch (vfoc) { - - case '0': *vfo = RIG_VFO_A; break; - case '1': *vfo = RIG_VFO_B; break; - default: - rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, buf[3]); - return -RIG_EVFO; - - } - rig->state.current_vfo = *vfo; - - /* Get mode of the VFO band */ - - snprintf(cmdbuf, 9, "VM %c", vfoc); - - retval = kenwood_safe_transaction(rig, cmdbuf, buf, 10, 6); - if (retval != RIG_OK) - return retval; - - *vfoch = buf[5]; - - return RIG_OK; -} - - - /* * tmd710_get_vfo * Assumes rig!=NULL */ -int -tmd710_get_vfo(RIG *rig, vfo_t *vfo) +int tmd710_get_vfo(RIG *rig, vfo_t *vfo) { - char vfoch; - int retval; + int vfomode; + int retval; - rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - retval = tmd710_get_vfo_char(rig, vfo, &vfoch); - if (retval != RIG_OK) - return retval; + retval = tmd710_get_vfo_and_mode(rig, vfo, &vfomode); + if (retval != RIG_OK) { + return retval; + } - switch (vfoch) { - case '0' : - case '1' : - break; - case '2' : - *vfo = RIG_VFO_MEM; - break; - default: - rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, vfoch); - return -RIG_EVFO; - } + switch (vfomode) { + case TMD710_BAND_MODE_VFO: + break; + case TMD710_BAND_MODE_MEMORY: + case TMD710_BAND_MODE_CALL: + *vfo = RIG_VFO_MEM; + break; + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO mode value '%c'\n", __func__, vfomode); + return -RIG_EVFO; + } - return RIG_OK; + return RIG_OK; } /* - * tm_set_vfo_bc2 - * Apply to split-capable models (with BC command taking 2 args): TM-V7, TM-D700 + * tmd710_set_vfo * * Assumes rig!=NULL */ -int tmd710_set_vfo (RIG *rig, vfo_t vfo) +int tmd710_set_vfo(RIG *rig, vfo_t vfo) { - struct kenwood_priv_data *priv = rig->state.priv; - char vfobuf[16], ackbuf[16]; - int vfonum, txvfonum, vfomode=0; - int retval; + char vfobuf[16], ackbuf[16]; + int vfonum, vfomode; + int retval; - rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); + rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); - switch (vfo) { - case RIG_VFO_A: - case RIG_VFO_VFO: - vfonum = 0; - /* put back split mode when toggling */ - txvfonum = (priv->split == RIG_SPLIT_ON && - rig->state.tx_vfo == RIG_VFO_B) ? 1 : vfonum; - break; - case RIG_VFO_B: - vfonum = 1; - /* put back split mode when toggling */ - txvfonum = (priv->split == RIG_SPLIT_ON && - rig->state.tx_vfo == RIG_VFO_A) ? 0 : vfonum; - break; - case RIG_VFO_MEM: - /* get current band */ - snprintf(vfobuf, 10, "BC"); - retval = kenwood_transaction(rig, vfobuf, ackbuf, sizeof (ackbuf)); - if (retval != RIG_OK) - return retval; - txvfonum = vfonum = ackbuf[3]-'0'; - vfomode = 2; - break; - - default: - rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %d\n", __func__, vfo); - return -RIG_EVFO; - } - - snprintf(vfobuf,9, "VM %d,%d", vfonum, vfomode); - retval = kenwood_transaction(rig, vfobuf, NULL, 0); - if (retval != RIG_OK) + switch (vfo) { + case RIG_VFO_A: + case RIG_VFO_VFO: + vfonum = TMD710_BAND_A; + vfomode = TMD710_BAND_MODE_VFO; + break; + case RIG_VFO_B: + vfonum = TMD710_BAND_B; + vfomode = TMD710_BAND_MODE_VFO; + break; + case RIG_VFO_MEM: + /* get current band */ + retval = tmd710_get_vfo_num(rig, &vfonum, NULL); + if (retval != RIG_OK) { return retval; + } + vfomode = TMD710_BAND_MODE_MEMORY; + break; + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %d\n", __func__, vfo); + return -RIG_EVFO; + } - if (vfo == RIG_VFO_MEM) - return RIG_OK; - - snprintf(vfobuf, 15, "BC %d,%d", vfonum, txvfonum); - retval = kenwood_transaction(rig, vfobuf, NULL, 0); - if (retval != RIG_OK) - return retval; + snprintf(vfobuf, sizeof(vfobuf), "VM %1d,%1d", vfonum, vfomode); + retval = kenwood_transaction(rig, vfobuf, ackbuf, sizeof(ackbuf)); + if (retval != RIG_OK) { + return retval; + } + if (vfo == RIG_VFO_MEM) { return RIG_OK; + } + + snprintf(vfobuf, sizeof(vfobuf), "BC %1d,%1d", vfonum, vfonum); + retval = kenwood_transaction(rig, vfobuf, ackbuf, sizeof(ackbuf)); + if (retval != RIG_OK) { + return retval; + } + + return RIG_OK; } int tmd710_get_mem(RIG *rig, vfo_t vfo, int *ch) { - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - - if (!rig || !ch) - return -RIG_EINVAL; - - char cmd[6]; + char cmd[16]; char membuf[16]; int retval; - char c; + int vfonum; int n; - if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) - { - if (RIG_OK != (retval = tmd710_get_vfo (rig, &vfo))) - { - return retval; - } - } - switch (vfo) - { - case RIG_VFO_A: c = '0'; break; - case RIG_VFO_B: c = '1'; break; - default: - rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %d\n", __func__, vfo); - return -RIG_EINVAL; - } - sprintf (cmd, "MR %c", c); - retval = kenwood_safe_transaction(rig, cmd, membuf, sizeof (membuf), 8); - if (retval != RIG_OK) - return retval; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - n = sscanf(membuf,"MR %*d,%d",ch); - if (n != 1) - { - rig_debug(RIG_DEBUG_ERR, "Unable to parse '%s', expected 'MR v,ccc'\n",membuf); - return -RIG_EPROTO; + if (!rig || !ch) { + return -RIG_EINVAL; + } + + if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { + retval = tmd710_get_vfo_num(rig, &vfonum, NULL); + if (retval != RIG_OK) { + return retval; } + } + + snprintf(cmd, sizeof(cmd), "MR %d", vfonum); + retval = kenwood_safe_transaction(rig, cmd, membuf, sizeof(membuf), 8); + if (retval != RIG_OK) { + return retval; + } + + n = sscanf(membuf, "MR %*d,%d", ch); + if (n != 1) { + rig_debug(RIG_DEBUG_ERR, "Unable to parse '%s', expected 'MR v,ccc'\n", membuf); + return -RIG_EPROTO; + } return RIG_OK; } int tmd710_set_mem(RIG *rig, vfo_t vfo, int ch) { - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - - if (!rig) - return -RIG_EINVAL; - + int retval, vfonum; char cmd[16]; char membuf[16]; - char c; - - if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) - { - int retval; - if (RIG_OK != (retval = tmd710_get_vfo (rig, &vfo))) - { - return retval; - } - } - switch (vfo) - { - case RIG_VFO_A: c = '0'; break; - case RIG_VFO_B: c = '1'; break; - default: - rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %d\n", __func__, vfo); - return -RIG_EINVAL; - } - sprintf (cmd, "MR %c,%03d", c, ch); - return kenwood_safe_transaction(rig, cmd, membuf, sizeof (membuf), 9); -} - -// set memory channel from current settings -int tmd710_set_channel(RIG *rig, const channel_t *chan) -{ -// char buf[65]; // Commented to quell GCC warning of unused variable. - N0NB - char mode, tx_mode = 0; - int tone = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - if (!rig || !chan) + if (!rig) { return -RIG_EINVAL; - - struct kenwood_priv_caps *caps = kenwood_caps(rig); - - mode = rmode2kenwood(chan->mode, caps->mode_table); - if (mode < 0 ) { - rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", - __func__, rig_strrmode(chan->mode)); - return -RIG_EINVAL; - } - - if (chan->split == RIG_SPLIT_ON) { - tx_mode = rmode2kenwood(chan->tx_mode, caps->mode_table); - if (tx_mode < 0 ) { - rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", - __func__, rig_strrmode(chan->tx_mode)); - return -RIG_EINVAL; - } - } - /* find tone */ - if (chan->ctcss_tone) { - - for (tone = 0; rig->caps->ctcss_list[tone] != 0; tone++) { - if (chan->ctcss_tone == rig->caps->ctcss_list[tone]) - break; + if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { + retval = tmd710_get_vfo_num(rig, &vfonum, NULL); + if (retval != RIG_OK) { + return retval; } - - if (chan->ctcss_tone != rig->caps->ctcss_list[tone]) - tone = 0; } -#if 0 - // waiting for kenwood reply on meaning of last two params - sprintf(buf, "ME %03d,%010"PRIll",%c,%c,%c,%c,%c,%c,%02d,%02d,%03d,%c,%8d,%c", - chan, - (int64_t)chan->freq, - '0' + chan->tuning_step, - '0' + chan->rptr_shift, - '0', // + chan->reverse, - '0' + chan->ctcss_sql, // on/off Tone - '0' + chan->ctcss, // on/off CT - '0' + chan->dcs_sql, // on/off CT + snprintf(cmd, sizeof(cmd), "MR %d,%03d", vfonum, ch); - chan->ctcss_tone, - chan->ct_freq, - '0' + chan->dcs_code, - chan->offset, - '0' + chan-mode); - - return kenwood_transaction(rig, buf, NULL, 0); -#else - return RIG_EINVAL; -#endif + return kenwood_safe_transaction(rig, cmd, membuf, sizeof(membuf), 8); } -// read memory channel into current settings int tmd710_get_channel(RIG *rig, channel_t *chan) { - int err; - tmd710_fo fo_struct; + int retval; + tmd710_me me_struct; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - if (!rig || !chan) + if (!rig || !chan) { return -RIG_EINVAL; - - // VFO should already be set up with all the needed info - // So we'll just copy from MEM to VFO - err = tmd710_pull_fo(rig, RIG_VFO_CURR, &fo_struct); - if (err != RIG_OK) return err; - - return RIG_OK; -} - -/* - * status: ok, no vfo checks - */ -int tmd710_get_dcs_sql(RIG * rig, vfo_t vfo, tone_t *code) -{ - int retval; - tmd710_fo fo_struct; - - if (!rig || !code) - return -RIG_EINVAL; - - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - if (retval != RIG_OK) return retval; - - *code = common_dcs_list[fo_struct.dcs_val]; - - return RIG_OK; -} - -/* - * status: ok, no vfo checks - */ -int tmd710_set_dcs_sql(RIG * rig, vfo_t vfo, tone_t code) -{ - int retval,i; - tmd710_fo fo_struct; - - // we only allow exact matches here - i=0; - while(code != common_dcs_list[i]) { - if(common_dcs_list[i] == 0) - return -RIG_EINVAL; - i++; } - retval = tmd710_pull_fo(rig,vfo,&fo_struct); - if (retval != RIG_OK) return retval; - fo_struct.dcs_val = i; - return tmd710_push_me(rig,vfo,&fo_struct); + retval = tmd710_pull_me(rig, chan->channel_num, &me_struct); + if (retval != RIG_OK) { + return retval; + } + + chan->freq = me_struct.freq; + chan->vfo = RIG_VFO_CURR; + + retval = tmd710_get_mode_hamlib_values(me_struct.mode, &chan->mode, &chan->width); + if (retval != RIG_OK) { + return retval; + } + + chan->tuning_step = rig->caps->tuning_steps[me_struct.step].ts; + + chan->funcs = 0; + + if (me_struct.tone != 0) { + chan->funcs |= RIG_FUNC_TONE; + } + if (me_struct.ct != 0) { + chan->funcs |= RIG_FUNC_TSQL; + } + if (me_struct.reverse != 0) { + chan->funcs |= RIG_FUNC_REV; + } + + chan->ctcss_tone = rig->caps->ctcss_list[me_struct.tone_freq]; + chan->ctcss_sql = rig->caps->ctcss_list[me_struct.ct_freq]; + chan->dcs_code = 0; + if (me_struct.dcs) { + chan->dcs_sql = common_dcs_list[me_struct.dcs_val]; + } else { + chan->dcs_sql = 0; + } + + retval = tmd710_get_rptr_shift_hamlib_value(me_struct.shift, &chan->rptr_shift); + if (retval != RIG_OK) { + return retval; + } + + chan->rptr_offs = me_struct.offset; + + retval = tmd710_get_memory_name(rig, chan->channel_num, chan->channel_desc); + if (retval != RIG_OK) { + return retval; + } + + chan->flags = RIG_CHFLAG_NONE; + + if (me_struct.lockout) { + chan->flags |= RIG_CHFLAG_SKIP; + } + + chan->tx_freq = me_struct.tx_freq; + + // Unsupported features + chan->bank_num = 0; + chan->ant = 0; + chan->split = RIG_SPLIT_OFF; + chan->tx_vfo = RIG_VFO_NONE; + chan->tx_mode = RIG_MODE_NONE; + chan->tx_width = 0; + chan->rit = 0; + chan->xit = 0; + chan->scan_group = 0; + // TODO: chan->levels + chan->ext_levels = NULL; + + return RIG_OK; } -/* end of file */ +int tmd710_set_channel(RIG *rig, const channel_t *chan) +{ + int retval; + tmd710_me me_struct; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !chan) { + return -RIG_EINVAL; + } + + me_struct.channel = chan->channel_num; + me_struct.freq = chan->freq; + me_struct.tx_freq = chan->tx_freq; + + retval = tmd710_find_tuning_step_index(rig, chan->tuning_step, &me_struct.step); + if (retval != RIG_OK) { + return retval; + } + + retval = tmd710_get_rptr_shift_tmd710_value(chan->rptr_shift, &me_struct.shift); + if (retval != RIG_OK) { + return retval; + } + + me_struct.offset = chan->rptr_offs; + + me_struct.reverse = (chan->funcs & RIG_FUNC_REV) ? 1 : 0; + me_struct.tone = (chan->funcs & RIG_FUNC_TONE) ? 1 : 0; + me_struct.ct = (chan->funcs & RIG_FUNC_TSQL) ? 1 : 0; + + if (!me_struct.tone && chan->ctcss_tone == 0) { + me_struct.tone_freq = 0; + } else { + retval = tmd710_find_ctcss_index(rig, chan->ctcss_tone, &me_struct.tone_freq); + if (retval != RIG_OK) { + return retval; + } + } + + if (!me_struct.ct && chan->ctcss_sql == 0) { + me_struct.ct_freq = 0; + } else { + retval = tmd710_find_ctcss_index(rig, chan->ctcss_sql, &me_struct.ct_freq); + if (retval != RIG_OK) { + return retval; + } + } + + if (chan->dcs_sql == 0) { + me_struct.dcs = 0; + me_struct.dcs_val = 0; + } else { + retval = tmd710_find_dcs_index(chan->dcs_sql, &me_struct.dcs_val); + if (retval != RIG_OK) { + return retval; + } + me_struct.dcs = 1; + } + + me_struct.lockout = (chan->flags & RIG_CHFLAG_SKIP) ? 1 : 0; + + retval = tmd710_get_mode_tmd710_value(chan->mode, &me_struct.mode); + if (retval != RIG_OK) { + return retval; + } + + me_struct.p15_unknown = 0; + + retval = tmd710_push_me(rig, &me_struct); + if (retval != RIG_OK) { + return retval; + } + + return tmd710_set_memory_name(rig, me_struct.channel, (char *) chan->channel_desc); +} + +int tmd710_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) +{ + char ackbuf[32]; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + return kenwood_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", ackbuf, sizeof(ackbuf)); +} + +int tmd710_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) +{ + char cmd[8], buf[8]; + int retval; + int vfonum, dcd_val; + + retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); + if (retval != RIG_OK) { + return retval; + } + + snprintf(cmd, sizeof(cmd), "BY %d", vfonum); + + retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), 6); + if (retval != RIG_OK) { + return retval; + } + + retval = sscanf(buf, "BY %d,%d", &vfonum, &dcd_val); + if (retval != 2) { + rig_debug(RIG_DEBUG_ERR, "%s: unexpected reply '%s', len=%d\n", __func__, buf); + return -RIG_EPROTO; + } + + switch (dcd_val) { + case 0: + *dcd = RIG_DCD_OFF; + break; + case 1: + *dcd = RIG_DCD_ON; + break; + default: + rig_debug(RIG_DEBUG_ERR, "%s: unexpected reply '%s', len=%d\n", __func__, buf); + return -RIG_ERJCTED; + } + + return RIG_OK; +} + +int tmd710_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) +{ + char ackbuf[8]; + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + switch (op) { + case RIG_OP_UP: + return kenwood_transaction(rig, "UP", ackbuf, sizeof(ackbuf)); + case RIG_OP_DOWN: + return kenwood_transaction(rig, "DW", ackbuf, sizeof(ackbuf)); + default: + return -RIG_EINVAL; + } +} + +/* + * tmd710_get_level + * Assumes rig!=NULL, val!=NULL + */ +int tmd710_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + char buf[10], ackbuf[20]; + int retval, v, l; + int vfonum; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); + if (retval != RIG_OK) { + return retval; + } + + switch (level) { + case RIG_LEVEL_RFPOWER: + snprintf(buf, sizeof(buf), "PC %d", vfonum); + retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); + if (retval != RIG_OK) + return retval; + + retval = sscanf(ackbuf, "PC %d,%d", &v, &l); + if (retval != 2 || l < 0 || l > 2) { + rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); + return -RIG_ERJCTED; + } + + /* range [0.0 ... 1.0] */ + val->f = (float) (l - TMD710_RF_POWER_MIN) / (float) (TMD710_RF_POWER_MAX - TMD710_RF_POWER_MIN); + + // RF power needs to be inverted + val->f = 1.0f - val->f; + break; + + case RIG_LEVEL_SQL: + snprintf(buf, sizeof(buf), "SQ %d", vfonum); + retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); + if (retval != RIG_OK) + return retval; + + retval = sscanf(ackbuf, "SQ %X", &l); + if (retval != 1 || l < TMD710_SQL_MIN || l > TMD710_SQL_MAX) { + rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); + return -RIG_ERJCTED; + } + + /* range [0.0 ... 1.0] */ + val->f = (float) (l - TMD710_SQL_MIN) / (float) (TMD710_SQL_MAX - TMD710_SQL_MIN); + break; + + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %d\n", __func__, level); + return -RIG_EINVAL; + } + + return RIG_OK; +} + +int tmd710_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + char buf[12], ackbuf[12]; + int vfonum; + int retval; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); + if (retval != RIG_OK) { + return retval; + } + + switch (level) { + case RIG_LEVEL_RFPOWER: + // RF power needs to be inverted + snprintf(buf, sizeof(buf), "PC %d,%d", vfonum, + (int) ((1.0f - val.f) * (TMD710_RF_POWER_MAX - TMD710_RF_POWER_MIN) + TMD710_RF_POWER_MIN)); + + return kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); + + case RIG_LEVEL_SQL: + snprintf(buf, sizeof(buf), "SQ %d,%02X", vfonum, + (int) (val.f * (TMD710_SQL_MAX - TMD710_SQL_MIN) + TMD710_SQL_MIN)); + return kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); + + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %d\n", __func__, level); + return -RIG_EINVAL; + } +} + +static int tmd710_tburst(RIG *rig, int status) +{ + char ackbuf[8]; + return kenwood_transaction(rig, (status == 1) ? "TT" : "RX", ackbuf, sizeof(ackbuf)); +} + +/* + * tmd710_get_kenwood_func + * Assumes rig!=NULL, status!=NULL + */ +static int tmd710_get_kenwood_func(RIG *rig, const char *cmd, int *status) +{ + char buf[8]; + int retval, len, expected; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + len = strlen(cmd); + expected = len + 2; + + retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), expected); + if (retval != RIG_OK) { + return retval; + } + + if (status) { + *status = (buf[len + 1] == '0') ? 0 : 1; + } + + return RIG_OK; +}; + +/* + * tmd710_set_kenwood_func + * Assumes rig!=NULL, status!=NULL + */ +static int tmd710_set_kenwood_func(RIG *rig, const char *cmd, int status) +{ + char buf[16], ackbuf[16]; + + rig_debug(RIG_DEBUG_TRACE, "%s: cmd = %s, status = %d\n", __func__, cmd, status); + + strncpy(buf, cmd, sizeof(buf) - 2); + buf[sizeof(buf) - 1] = '\0'; + strncat(buf, status ? " 1" : " 0", sizeof(buf) - 1); + + return kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); +} + +/* + * tmd710_get_func + * Assumes rig!=NULL, status!=NULL + */ +int tmd710_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) +{ + int retval; + int use_fo = 0, use_mu = 0; + tmd710_fo fo_struct; + tmd710_mu mu_struct; + + rig_debug(RIG_DEBUG_TRACE, "%s: called (0x%04x)\n", __func__, func); + + switch (func) { + case RIG_FUNC_TONE: + case RIG_FUNC_TSQL: + case RIG_FUNC_REV: + use_fo = 1; + break; + case RIG_FUNC_ARO: + case RIG_FUNC_AIP: + case RIG_FUNC_RESUME: + use_mu = 1; + break; + } + + if (use_fo) { + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; + } + } + + if (use_mu) { + retval = tmd710_pull_mu(rig, &mu_struct); + if (retval != RIG_OK) { + return retval; + } + } + + switch (func) { + case RIG_FUNC_TONE: + *status = (fo_struct.tone != 0) ? 1 : 0; + break; + case RIG_FUNC_TSQL: + *status = (fo_struct.ct != 0) ? 1 : 0; + break; + case RIG_FUNC_REV: + *status = (fo_struct.reverse != 0) ? 1 : 0; + break; + case RIG_FUNC_LOCK: + return tmd710_get_kenwood_func(rig, "LK", status); + case RIG_FUNC_ARO: + *status = (mu_struct.auto_repeater_offset != 0) ? 1 : 0; + break; + case RIG_FUNC_AIP: + *status = ((mu_struct.vhf_aip != 0) || (mu_struct.uhf_aip != 0)) ? 1 : 0; + break; + case RIG_FUNC_RESUME: + *status = (mu_struct.scan_resume == TMD710_SCAN_RESUME_TIME) ? 1 : 0; + break; + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported function %#x\n", __func__, func); + return -RIG_EINVAL; + } + + return RIG_OK; +} + +/* + * tmd710_set_func + * Assumes rig!=NULL, status!=NULL + */ +int tmd710_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) +{ + int retval; + int use_fo = 0, use_mu = 0; + tmd710_fo fo_struct; + tmd710_mu mu_struct; + + rig_debug(RIG_DEBUG_TRACE, "%s: called (0x%04x)\n", __func__, func); + + switch (func) { + case RIG_FUNC_TONE: + case RIG_FUNC_TSQL: + case RIG_FUNC_REV: + use_fo = 1; + break; + case RIG_FUNC_ARO: + case RIG_FUNC_AIP: + case RIG_FUNC_RESUME: + use_mu = 1; + break; + } + + if (use_fo) { + retval = tmd710_pull_fo(rig, vfo, &fo_struct); + if (retval != RIG_OK) { + return retval; + } + } + + if (use_mu) { + retval = tmd710_pull_mu(rig, &mu_struct); + if (retval != RIG_OK) { + return retval; + } + } + + switch (func) { + case RIG_FUNC_TONE: + fo_struct.tone = status ? 1 : 0; + break; + case RIG_FUNC_TSQL: + fo_struct.ct = status ? 1 : 0; + break; + case RIG_FUNC_REV: + fo_struct.reverse = status ? 1 : 0; + break; + case RIG_FUNC_ARO: + mu_struct.auto_repeater_offset = status ? 1 : 0; + break; + case RIG_FUNC_AIP: + mu_struct.vhf_aip = status ? 1 : 0; + mu_struct.uhf_aip = status ? 1 : 0; + break; + case RIG_FUNC_RESUME: + mu_struct.scan_resume = status ? TMD710_SCAN_RESUME_TIME : TMD710_SCAN_RESUME_CARRIER; + break; + case RIG_FUNC_LOCK: + return tmd710_set_kenwood_func(rig, "LK", status); + case RIG_FUNC_TBURST: + return tmd710_tburst(rig, status); + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported function %#x\n", __func__, func); + return -RIG_EINVAL; + } + + if (use_fo) { + return tmd710_push_fo(rig, vfo, &fo_struct); + } + + if (use_mu) { + return tmd710_push_mu(rig, &mu_struct); + } + + return -RIG_EINVAL; +} + +/* + * tmd710_get_parm + * Assumes rig!=NULL, status!=NULL + */ +int tmd710_get_parm(RIG *rig, setting_t parm, value_t *val) +{ + int retval; + tmd710_mu mu_struct; + + rig_debug(RIG_DEBUG_TRACE, "%s: called (0x%04x)\n", __func__, parm); + + retval = tmd710_pull_mu(rig, &mu_struct); + if (retval != RIG_OK) { + return retval; + } + + switch (parm) { + case RIG_PARM_BEEP: + val->i = mu_struct.beep ? 1 : 0; + break; + case RIG_PARM_APO: + if (mu_struct.auto_power_off == TMD710_AUTO_POWER_OFF_180MIN) { + val->i = 180; + } else { + val->i = mu_struct.auto_power_off * 30; + } + break; + case RIG_PARM_BACKLIGHT: + val->f = ((float) mu_struct.brightness_level) / 8.0f; + break; + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported parm %#x\n", __func__, parm); + return -RIG_EINVAL; + } + + return RIG_OK; +} + +int tmd710_set_parm(RIG *rig, setting_t parm, value_t val) +{ + int retval; + tmd710_mu mu_struct; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + retval = tmd710_pull_mu(rig, &mu_struct); + if (retval != RIG_OK) { + return retval; + } + + switch (parm) { + case RIG_PARM_BEEP: + mu_struct.beep = val.i ? 1 : 0; + break; + case RIG_PARM_BACKLIGHT: + if (val.f < 0 || val.f > 1) { + return -RIG_EINVAL; + } + + mu_struct.brightness_level = (int) (val.f * 8); + break; + case RIG_PARM_APO: { + int value = 0; + + if (val.i > 120) { + value = TMD710_AUTO_POWER_OFF_180MIN; + } else if (val.i > 90) { + value = TMD710_AUTO_POWER_OFF_120MIN; + } else if (val.i > 60) { + value = TMD710_AUTO_POWER_OFF_90MIN; + } else if (val.i > 30) { + value = TMD710_AUTO_POWER_OFF_60MIN; + } else if (val.i > 0) { + value = TMD710_AUTO_POWER_OFF_30MIN; + } + + mu_struct.auto_power_off = value; + break; + } + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported parm %#x\n", __func__, parm); + return -RIG_EINVAL; + } + + return tmd710_push_mu(rig, &mu_struct); +} + +/* + * tmd710_get_ext_level + * Assumes rig!=NULL, rig->state.priv!=NULL, val!=NULL + * + */ +int tmd710_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val) { + int retval; + tmd710_mu mu_struct; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + retval = tmd710_pull_mu(rig, &mu_struct); + if (retval != RIG_OK) { + return retval; + } + + switch (token) { + case TOK_LEVEL_EXT_DATA_BAND: + val->i = mu_struct.ext_data_band; + break; + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %d\n", __func__, token); + return -RIG_EINVAL; + } + + return RIG_OK; +} + +/* + * tmd710_set_ext_level + * Assumes rig!=NULL, rig->state.priv!=NULL + * + */ +int tmd710_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val) { + int retval; + tmd710_mu mu_struct; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + retval = tmd710_pull_mu(rig, &mu_struct); + if (retval != RIG_OK) { + return retval; + } + + switch (token) { + case TOK_LEVEL_EXT_DATA_BAND: { + int v = val.i; + if (v != TMD710_EXT_DATA_BAND_A && v != TMD710_EXT_DATA_BAND_B + && v != TMD710_EXT_DATA_BAND_TXA_RXB && v != TMD710_EXT_DATA_BAND_TXB_RXA) { + return -RIG_EINVAL; + } + + mu_struct.ext_data_band = v; + break; + } + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %d\n", __func__, token); + return -RIG_EINVAL; + } + + return tmd710_push_mu(rig, &mu_struct); +} diff --git a/src/misc.c b/src/misc.c index aa10a2696..77c46f12d 100644 --- a/src/misc.c +++ b/src/misc.c @@ -319,6 +319,7 @@ static struct { RIG_MODE_LSB, "LSB" }, { RIG_MODE_RTTY, "RTTY" }, { RIG_MODE_FM, "FM" }, + { RIG_MODE_FMN, "FMN" }, { RIG_MODE_WFM, "WFM" }, { RIG_MODE_CWR, "CWR" }, { RIG_MODE_RTTYR, "RTTYR" },