diff --git a/include/hamlib/riglist.h b/include/hamlib/riglist.h index 186ad5bcf..7cbc0a267 100644 --- a/include/hamlib/riglist.h +++ b/include/hamlib/riglist.h @@ -110,7 +110,7 @@ #define RIG_MODEL_FT980 RIG_MAKE_MODEL(RIG_YAESU, 31) #define RIG_MODEL_FTDX5000 RIG_MAKE_MODEL(RIG_YAESU, 32) #define RIG_MODEL_VX1700 RIG_MAKE_MODEL(RIG_YAESU, 33) -#define RIG_MODEL_FT1200 RIG_MAKE_MODEL(RIG_YAESU, 34) +#define RIG_MODEL_FTDX1200 RIG_MAKE_MODEL(RIG_YAESU, 34) #define RIG_MODEL_FT991 RIG_MAKE_MODEL(RIG_YAESU, 35) #define RIG_MODEL_FT891 RIG_MAKE_MODEL(RIG_YAESU, 36) #define RIG_MODEL_FTDX3000 RIG_MAKE_MODEL(RIG_YAESU, 37) diff --git a/rigs/yaesu/Makefile.am b/rigs/yaesu/Makefile.am index 9afd547d3..422bf22a3 100644 --- a/rigs/yaesu/Makefile.am +++ b/rigs/yaesu/Makefile.am @@ -10,7 +10,7 @@ YAESUSRC = ft100.c ft100.h ft747.c ft747.h ft817.c ft817.h ft847.c ft847.h \ ## Yaesu radios that use the new Kenwood style CAT commands NEWCATSRC = newcat.c newcat.h ft450.c ft450.h ft950.c ft950.h ft991.c ft991.h \ ft2000.c ft2000.h ft9000.c ft9000.h ft5000.c ft5000.h ft1200.c ft1200.h \ - ft891.c ft891.h + ft891.c ft891.h ftdx101.c ftdx101.h ft3000.c noinst_LTLIBRARIES = libhamlib-yaesu.la libhamlib_yaesu_la_SOURCES = $(YAESUSRC) $(NEWCATSRC) yaesu.c yaesu.h diff --git a/rigs/yaesu/ft1200.c b/rigs/yaesu/ft1200.c index 604d55b91..7706d463c 100644 --- a/rigs/yaesu/ft1200.c +++ b/rigs/yaesu/ft1200.c @@ -1,7 +1,7 @@ /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * - * ft2000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) + * ft1200.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * ft1200.c - (C) David Fannin 2015 (kk6df at arrl.net) @@ -33,24 +33,57 @@ #include "hamlib/rig.h" #include "bandplan.h" -#include "serial.h" -#include "misc.h" -#include "yaesu.h" #include "newcat.h" #include "ft1200.h" #include "idx_builtin.h" #include "tones.h" -/* - * ft1200 rigs capabilities. - * Also this struct is READONLY! - * - */ - -const struct rig_caps ft1200_caps = +const struct newcat_priv_caps ftdx1200_priv_caps = { - RIG_MODEL(RIG_MODEL_FT1200), - .model_name = "FT-1200", + .roofing_filter_count = 7, + .roofing_filters = + { + // The index must match ext level combo index + { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, + { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, + { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, + { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, + { .index = 4, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, + { .index = 5, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, + { .index = 6, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, + } +}; + +const struct confparams ftdx1200_ext_levels[] = +{ + { + TOK_ROOFING_FILTER, + "ROOFINGFILTER", + "Roofing filter", + "Roofing filter", + NULL, + RIG_CONF_COMBO, + { .c = { .combostr = { + "AUTO", "15 kHz", "6 kHz", "3 kHz", + "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", + NULL } + } } + }, + { RIG_CONF_END, NULL, } +}; + +int ftdx1200_ext_tokens[] = +{ + TOK_ROOFING_FILTER, TOK_BACKEND_NONE +}; + +/* + * FTDX 1200 rig capabilities + */ +const struct rig_caps ftdx1200_caps = +{ + RIG_MODEL(RIG_MODEL_FTDX1200), + .model_name = "FTDX 1200", .mfg_name = "Yaesu", .version = NEWCAT_VER ".0", .copyright = "LGPL", @@ -65,14 +98,14 @@ const struct rig_caps ft1200_caps = .serial_stop_bits = 1, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, - .write_delay = FT1200_WRITE_DELAY, - .post_write_delay = FT1200_POST_WRITE_DELAY, + .write_delay = FTDX1200_WRITE_DELAY, + .post_write_delay = FTDX1200_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, - .has_get_func = FT1200_FUNCS, - .has_set_func = FT1200_FUNCS, - .has_get_level = FT1200_LEVELS, - .has_set_level = RIG_LEVEL_SET(FT1200_LEVELS), + .has_get_func = FTDX1200_FUNCS, + .has_set_func = FTDX1200_FUNCS, + .has_get_level = FTDX1200_LEVELS, + .has_set_level = RIG_LEVEL_SET(FTDX1200_LEVELS), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { @@ -87,12 +120,12 @@ const struct rig_caps ft1200_caps = .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), - .vfo_ops = FT1200_VFO_OPS, + .vfo_ops = FTDX1200_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 1200 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, - .str_cal = FT1200_STR_CAL, + .str_cal = FTDX1200_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ @@ -101,42 +134,42 @@ const struct rig_caps ft1200_caps = .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ - {kHz(30), MHz(56), FT1200_ALL_RX_MODES, -1, -1, FT1200_VFO_ALL, FT1200_TX_ANTS}, + {kHz(30), MHz(56), FTDX1200_ALL_RX_MODES, -1, -1, FTDX1200_VFO_ALL, FTDX1200_TX_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { - FRQ_RNG_HF(1, FT1200_OTHER_TX_MODES, W(5), W(100), FT1200_VFO_ALL, FT1200_TX_ANTS), - FRQ_RNG_HF(1, FT1200_AM_TX_MODES, W(2), W(25), FT1200_VFO_ALL, FT1200_TX_ANTS), /* AM class */ - FRQ_RNG_6m(1, FT1200_OTHER_TX_MODES, W(5), W(100), FT1200_VFO_ALL, FT1200_TX_ANTS), - FRQ_RNG_6m(1, FT1200_AM_TX_MODES, W(2), W(25), FT1200_VFO_ALL, FT1200_TX_ANTS), /* AM class */ + FRQ_RNG_HF(1, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), + FRQ_RNG_HF(1, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ + FRQ_RNG_6m(1, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), + FRQ_RNG_6m(1, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { - {kHz(30), MHz(56), FT1200_ALL_RX_MODES, -1, -1, FT1200_VFO_ALL, FT1200_TX_ANTS}, + {kHz(30), MHz(56), FTDX1200_ALL_RX_MODES, -1, -1, FTDX1200_VFO_ALL, FTDX1200_TX_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { - FRQ_RNG_HF(2, FT1200_OTHER_TX_MODES, W(5), W(100), FT1200_VFO_ALL, FT1200_TX_ANTS), - FRQ_RNG_HF(2, FT1200_AM_TX_MODES, W(2), W(25), FT1200_VFO_ALL, FT1200_TX_ANTS), /* AM class */ - FRQ_RNG_6m(2, FT1200_OTHER_TX_MODES, W(5), W(100), FT1200_VFO_ALL, FT1200_TX_ANTS), - FRQ_RNG_6m(2, FT1200_AM_TX_MODES, W(2), W(25), FT1200_VFO_ALL, FT1200_TX_ANTS), /* AM class */ + FRQ_RNG_HF(2, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), + FRQ_RNG_HF(2, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ + FRQ_RNG_6m(2, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), + FRQ_RNG_6m(2, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { - {FT1200_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ - {FT1200_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ + {FTDX1200_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ + {FTDX1200_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ - {FT1200_AM_RX_MODES, Hz(100)}, /* Normal */ - {FT1200_AM_RX_MODES, kHz(1)}, /* Fast */ + {FTDX1200_AM_RX_MODES, Hz(100)}, /* Normal */ + {FTDX1200_AM_RX_MODES, kHz(1)}, /* Fast */ - {FT1200_FM_RX_MODES, Hz(100)}, /* Normal */ - {FT1200_FM_RX_MODES, kHz(1)}, /* Fast */ + {FTDX1200_FM_RX_MODES, Hz(100)}, /* Normal */ + {FTDX1200_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, @@ -144,21 +177,24 @@ const struct rig_caps ft1200_caps = /* mode/filter list, .remember = order matters! */ .filters = { - {FT1200_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Normal CW, RTTY, PKT/USER */ - {FT1200_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ - {FT1200_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ + {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Normal CW, RTTY, PKT/USER */ + {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ + {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ - {FT1200_FM_RX_MODES, Hz(12000)}, /* Normal FM */ - {FT1200_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ + {FTDX1200_FM_RX_MODES, Hz(12000)}, /* Normal FM */ + {FTDX1200_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ RIG_FLT_END, }, - .priv = NULL, + .ext_tokens = ftdx1200_ext_tokens, + .extlevels = ftdx1200_ext_levels, + + .priv = &ftdx1200_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, @@ -208,5 +244,7 @@ const struct rig_caps ft1200_caps = .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, + .set_ext_level = newcat_set_ext_level, + .get_ext_level = newcat_get_ext_level, }; diff --git a/rigs/yaesu/ft1200.h b/rigs/yaesu/ft1200.h index 78f2555fe..7910be05a 100644 --- a/rigs/yaesu/ft1200.h +++ b/rigs/yaesu/ft1200.h @@ -1,7 +1,7 @@ /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * - * ft2000.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) + * ft1200.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * ft1200.h - (C) David Fannin 2015 (kk6df at arrl.net) @@ -26,63 +26,54 @@ */ -#ifndef _FT1200_H -#define _FT1200_H 1 +#ifndef _FTDX1200_H +#define _FTDX1200_H 1 -#if 0 -#define TRUE 1 -#define FALSE 0 -#define ON TRUE -#define OFF FALSE -#endif - -#define FT1200_VFO_ALL (RIG_VFO_A|RIG_VFO_B) +#define FTDX1200_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ -#define FT1200_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ - RIG_MODE_RTTY|RIG_MODE_RTTYR|\ - RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) +#define FTDX1200_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ + RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM) -#define FT1200_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ +#define FTDX1200_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) -#define FT1200_AM_RX_MODES (RIG_MODE_AM) -#define FT1200_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) -#define FT1200_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ +#define FTDX1200_AM_RX_MODES (RIG_MODE_AM) +#define FTDX1200_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) +#define FTDX1200_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) - - - /* TRX caps */ -#define FT1200_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ - RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) /* 100 W class */ -#define FT1200_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ +#define FTDX1200_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ + RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM) /* 100 W class */ +#define FTDX1200_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ /* TBC */ -#define FT1200_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ - RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_SWR|\ +#define FTDX1200_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ + RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ - RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF) + RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ + RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|\ + RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER) /* TBC */ -#define FT1200_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ +#define FTDX1200_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_TUNER) /* TBC */ -#define FT1200_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ +#define FTDX1200_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) /* TBC */ -#define FT1200_STR_CAL { 16, \ +#define FTDX1200_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ @@ -108,14 +99,14 @@ * */ -#define FT1200_TX_ANTS (RIG_ANT_1|RIG_ANT_2) +#define FTDX1200_TX_ANTS (RIG_ANT_1|RIG_ANT_2) -#define FT1200_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ -#define FT1200_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ -#define FT1200_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ -#define FT1200_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ -#define FT1200_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ -#define FT1200_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ +#define FTDX1200_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ +#define FTDX1200_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ +#define FTDX1200_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ +#define FTDX1200_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ +#define FTDX1200_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ +#define FTDX1200_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ @@ -125,11 +116,11 @@ /* Delay between bytes sent to FT-2000 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ -#define FT1200_WRITE_DELAY 0 +#define FTDX1200_WRITE_DELAY 0 /* Delay sequential fast writes */ -#define FT1200_POST_WRITE_DELAY 5 +#define FTDX1200_POST_WRITE_DELAY 5 -#endif /* _FT1200_H */ +#endif /* _FTDX1200_H */ diff --git a/rigs/yaesu/ft3000.c b/rigs/yaesu/ft3000.c new file mode 100644 index 000000000..516a181b4 --- /dev/null +++ b/rigs/yaesu/ft3000.c @@ -0,0 +1,254 @@ +/* + * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) + * + * ft3000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) + * (C) Stephane Fillod 2008-2010 + * (C) Terry Embry 2008-2009 + * + * This shared library provides an API for communicating + * via serial interface to an FT-DX3000 using the "CAT" interface + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "hamlib/rig.h" +#include "bandplan.h" +#include "newcat.h" +#include "ft5000.h" +#include "idx_builtin.h" +#include "tones.h" + +const struct newcat_priv_caps ftdx3000_priv_caps = +{ + .roofing_filter_count = 11, + .roofing_filters = + { + // The index must match ext level combo index + { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, + { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, + { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, + { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, + { .index = 4, .set_value = '4', .get_value = '7', .width = 600, .optional = 0 }, + { .index = 5, .set_value = '5', .get_value = '8', .width = 300, .optional = 0 }, + { .index = 6, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, + { .index = 7, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, + { .index = 8, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, + { .index = 9, .set_value = 0, .get_value = '9', .width = 600, .optional = 0 }, + { .index = 10, .set_value = 0, .get_value = 'A', .width = 300, .optional = 0 }, + } +}; + +const struct confparams ftdx3000_ext_levels[] = +{ + { + TOK_ROOFING_FILTER, + "ROOFINGFILTER", + "Roofing filter", + "Roofing filter", + NULL, + RIG_CONF_COMBO, + { .c = { .combostr = { + "AUTO", "15 kHz", "6 kHz", "3 kHz", "600 Hz", "300 Hz", + "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", "AUTO - 600 Hz", "AUTO - 300 Hz", + NULL } + } } + }, + { RIG_CONF_END, NULL, } +}; + +int ftdx3000_ext_tokens[] = +{ + TOK_ROOFING_FILTER, TOK_BACKEND_NONE +}; + +/* + * FTDX 3000 rig capabilities + * Seems to be largely compatible with the FTDX 5000, + * so this is just a copy of the FTDX 5000 caps. + * It really needs to be reviewed for accuracy, but it works for WSJT-X. + */ +const struct rig_caps ftdx3000_caps = +{ + RIG_MODEL(RIG_MODEL_FTDX3000), + .model_name = "FTDX 3000", + .mfg_name = "Yaesu", + .version = NEWCAT_VER ".2", + .copyright = "LGPL", + .status = RIG_STATUS_STABLE, + .rig_type = RIG_TYPE_TRANSCEIVER, + .ptt_type = RIG_PTT_RIG, + .dcd_type = RIG_DCD_NONE, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 4800, /* Default rate per manual */ + .serial_rate_max = 38400, + .serial_data_bits = 8, + .serial_stop_bits = 1, /* Assumed since manual makes no mention */ + .serial_parity = RIG_PARITY_NONE, + .serial_handshake = RIG_HANDSHAKE_HARDWARE, + .write_delay = FTDX5000_WRITE_DELAY, + .post_write_delay = FTDX5000_POST_WRITE_DELAY, + .timeout = 2000, + .retry = 3, + .has_get_func = FTDX5000_FUNCS, + .has_set_func = FTDX5000_FUNCS, + .has_get_level = FTDX5000_LEVELS, + .has_set_level = RIG_LEVEL_SET(FTDX5000_LEVELS), + .has_get_parm = RIG_PARM_NONE, + .has_set_parm = RIG_PARM_NONE, + .level_gran = { + [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, + }, + .ctcss_list = common_ctcss_list, + .dcs_list = NULL, + .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ + .attenuator = { 6, 12, 18, RIG_DBLST_END, }, + .max_rit = Hz(9999), + .max_xit = Hz(9999), + .max_ifshift = Hz(1000), + .vfo_ops = FTDX5000_VFO_OPS, + .targetable_vfo = RIG_TARGETABLE_FREQ, /* one of the few diffs from the 5000 */ + .transceive = RIG_TRN_OFF, /* May enable later as the 5000 has an Auto Info command */ + .bank_qty = 0, + .chan_desc_sz = 0, + .str_cal = FTDX5000_STR_CAL, + .chan_list = { + { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, + { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ + RIG_CHAN_END, + }, + + .rx_range_list1 = { + /* General coverage + ham, ANT_5 is RX only antenna */ + {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "USA"}, + RIG_FRNG_END, + }, + + .tx_range_list1 = { + FRQ_RNG_HF(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), + FRQ_RNG_HF(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ + FRQ_RNG_6m(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), + FRQ_RNG_6m(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ + + RIG_FRNG_END, + }, + + .rx_range_list2 = { + {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "EUR"}, + RIG_FRNG_END, + }, + + .tx_range_list2 = { + FRQ_RNG_HF(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), + FRQ_RNG_HF(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ + FRQ_RNG_6m(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), + FRQ_RNG_6m(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ + + RIG_FRNG_END, + }, + + .tuning_steps = { + {FTDX5000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ + {FTDX5000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ + + {FTDX5000_AM_RX_MODES, Hz(100)}, /* Normal */ + {FTDX5000_AM_RX_MODES, kHz(1)}, /* Fast */ + + {FTDX5000_FM_RX_MODES, Hz(100)}, /* Normal */ + {FTDX5000_FM_RX_MODES, kHz(1)}, /* Fast */ + + RIG_TS_END, + + }, + + /* mode/filter list, .remember = order matters! */ + .filters = { + {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ + {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ + {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ + {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ + {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ + {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ + {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ + {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ + {FTDX5000_FM_RX_MODES, Hz(15000)}, /* Normal FM */ + {FTDX5000_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ + + RIG_FLT_END, + }, + + .ext_tokens = ftdx3000_ext_tokens, + .extlevels = ftdx3000_ext_levels, + + .priv = &ftdx3000_priv_caps, + + .rig_init = newcat_init, + .rig_cleanup = newcat_cleanup, + .rig_open = newcat_open, /* port opened */ + .rig_close = newcat_close, /* port closed */ + + .cfgparams = newcat_cfg_params, + .set_conf = newcat_set_conf, + .get_conf = newcat_get_conf, + .set_freq = newcat_set_freq, + .get_freq = newcat_get_freq, + .set_mode = newcat_set_mode, + .get_mode = newcat_get_mode, + .set_vfo = newcat_set_vfo, + .get_vfo = newcat_get_vfo, + .set_ptt = newcat_set_ptt, + .get_ptt = newcat_get_ptt, + .set_split_vfo = newcat_set_split_vfo, + .get_split_vfo = newcat_get_split_vfo, + .set_rit = newcat_set_rit, + .get_rit = newcat_get_rit, + .set_xit = newcat_set_xit, + .get_xit = newcat_get_xit, + .set_ant = newcat_set_ant, + .get_ant = newcat_get_ant, + .get_func = newcat_get_func, + .set_func = newcat_set_func, + .get_level = newcat_get_level, + .set_level = newcat_set_level, + .get_mem = newcat_get_mem, + .set_mem = newcat_set_mem, + .vfo_op = newcat_vfo_op, + .get_info = newcat_get_info, + .power2mW = newcat_power2mW, + .mW2power = newcat_mW2power, + .set_rptr_shift = newcat_set_rptr_shift, + .get_rptr_shift = newcat_get_rptr_shift, + .set_ctcss_tone = newcat_set_ctcss_tone, + .get_ctcss_tone = newcat_get_ctcss_tone, + .set_ctcss_sql = newcat_set_ctcss_sql, + .get_ctcss_sql = newcat_get_ctcss_sql, + .set_powerstat = newcat_set_powerstat, + .get_powerstat = newcat_get_powerstat, + .get_ts = newcat_get_ts, + .set_ts = newcat_set_ts, + .set_trn = newcat_set_trn, + .get_trn = newcat_get_trn, + .set_channel = newcat_set_channel, + .get_channel = newcat_get_channel, + .set_ext_level = newcat_set_ext_level, + .get_ext_level = newcat_get_ext_level, + +}; diff --git a/rigs/yaesu/ft5000.c b/rigs/yaesu/ft5000.c index 61ffc0e42..c02df103a 100644 --- a/rigs/yaesu/ft5000.c +++ b/rigs/yaesu/ft5000.c @@ -1,7 +1,7 @@ /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * - * ft2000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) + * ft5000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * @@ -25,31 +25,64 @@ * */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "hamlib/rig.h" #include "bandplan.h" -#include "serial.h" -#include "misc.h" -#include "yaesu.h" #include "newcat.h" #include "ft5000.h" #include "idx_builtin.h" #include "tones.h" -/* - * ft5000 rigs capabilities. - * Also this struct is READONLY! - * - */ +const struct newcat_priv_caps ftdx5000_priv_caps = +{ + .roofing_filter_count = 11, + .roofing_filters = + { + // The index must match ext level combo index + { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, + { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, + { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, + { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, + { .index = 4, .set_value = '4', .get_value = '7', .width = 600, .optional = 0 }, + { .index = 5, .set_value = '5', .get_value = '8', .width = 300, .optional = 0 }, + { .index = 6, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, + { .index = 7, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, + { .index = 8, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, + { .index = 9, .set_value = 0, .get_value = '9', .width = 600, .optional = 0 }, + { .index = 10, .set_value = 0, .get_value = 'A', .width = 300, .optional = 0 }, + } +}; + +const struct confparams ftdx5000_ext_levels[] = +{ + { + TOK_ROOFING_FILTER, + "ROOFINGFILTER", + "Roofing filter", + "Roofing filter", + NULL, + RIG_CONF_COMBO, + { .c = { .combostr = { + "AUTO", "15 kHz", "6 kHz", "3 kHz", "600 Hz (Main)", "300 Hz (Main)", + "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", "AUTO - 600 Hz (Main)", "AUTO - 300 Hz (Main)", + NULL } + } } + }, + { RIG_CONF_END, NULL, } +}; + +int ftdx5000_ext_tokens[] = +{ + TOK_ROOFING_FILTER, TOK_BACKEND_NONE +}; const struct rig_caps ftdx5000_caps = { RIG_MODEL(RIG_MODEL_FTDX5000), - .model_name = "FT-DX5000", + .model_name = "FTDX 5000", .mfg_name = "Yaesu", .version = NEWCAT_VER ".0", .copyright = "LGPL", @@ -157,344 +190,10 @@ const struct rig_caps ftdx5000_caps = RIG_FLT_END, }, - .priv = NULL, - - .rig_init = newcat_init, - .rig_cleanup = newcat_cleanup, - .rig_open = newcat_open, /* port opened */ - .rig_close = newcat_close, /* port closed */ - - .cfgparams = newcat_cfg_params, - .set_conf = newcat_set_conf, - .get_conf = newcat_get_conf, - .set_freq = newcat_set_freq, - .get_freq = newcat_get_freq, - .set_mode = newcat_set_mode, - .get_mode = newcat_get_mode, - .set_vfo = newcat_set_vfo, - .get_vfo = newcat_get_vfo, - .set_ptt = newcat_set_ptt, - .get_ptt = newcat_get_ptt, - .set_split_vfo = newcat_set_split_vfo, - .get_split_vfo = newcat_get_split_vfo, - .set_rit = newcat_set_rit, - .get_rit = newcat_get_rit, - .set_xit = newcat_set_xit, - .get_xit = newcat_get_xit, - .set_ant = newcat_set_ant, - .get_ant = newcat_get_ant, - .get_func = newcat_get_func, - .set_func = newcat_set_func, - .get_level = newcat_get_level, - .set_level = newcat_set_level, - .get_mem = newcat_get_mem, - .set_mem = newcat_set_mem, - .vfo_op = newcat_vfo_op, - .get_info = newcat_get_info, - .power2mW = newcat_power2mW, - .mW2power = newcat_mW2power, - .set_rptr_shift = newcat_set_rptr_shift, - .get_rptr_shift = newcat_get_rptr_shift, - .set_ctcss_tone = newcat_set_ctcss_tone, - .get_ctcss_tone = newcat_get_ctcss_tone, - .set_ctcss_sql = newcat_set_ctcss_sql, - .get_ctcss_sql = newcat_get_ctcss_sql, - .set_powerstat = newcat_set_powerstat, - .get_powerstat = newcat_get_powerstat, - .get_ts = newcat_get_ts, - .set_ts = newcat_set_ts, - .set_trn = newcat_set_trn, - .get_trn = newcat_get_trn, - .set_channel = newcat_set_channel, - .get_channel = newcat_get_channel, - -}; - -/* - * ft3000 rig capabilities. - * Seems to be largely compatible with the ft5000 - * So this is just a copy of the 5000 caps - * Also this struct is READONLY! - * It really needs to be reviewed for accuracy but it works for WSJT-X - * - */ - -const struct rig_caps ftdx3000_caps = -{ - RIG_MODEL(RIG_MODEL_FTDX3000), - .model_name = "FT-DX3000", - .mfg_name = "Yaesu", - .version = NEWCAT_VER ".2", - .copyright = "LGPL", - .status = RIG_STATUS_STABLE, - .rig_type = RIG_TYPE_TRANSCEIVER, - .ptt_type = RIG_PTT_RIG, - .dcd_type = RIG_DCD_NONE, - .port_type = RIG_PORT_SERIAL, - .serial_rate_min = 4800, /* Default rate per manual */ - .serial_rate_max = 38400, - .serial_data_bits = 8, - .serial_stop_bits = 1, /* Assumed since manual makes no mention */ - .serial_parity = RIG_PARITY_NONE, - .serial_handshake = RIG_HANDSHAKE_HARDWARE, - .write_delay = FTDX5000_WRITE_DELAY, - .post_write_delay = FTDX5000_POST_WRITE_DELAY, - .timeout = 2000, - .retry = 3, - .has_get_func = FTDX5000_FUNCS, - .has_set_func = FTDX5000_FUNCS, - .has_get_level = FTDX5000_LEVELS, - .has_set_level = RIG_LEVEL_SET(FTDX5000_LEVELS), - .has_get_parm = RIG_PARM_NONE, - .has_set_parm = RIG_PARM_NONE, - .level_gran = { - [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, - [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, - }, - .ctcss_list = common_ctcss_list, - .dcs_list = NULL, - .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ - .attenuator = { 6, 12, 18, RIG_DBLST_END, }, - .max_rit = Hz(9999), - .max_xit = Hz(9999), - .max_ifshift = Hz(1000), - .vfo_ops = FTDX5000_VFO_OPS, - .targetable_vfo = RIG_TARGETABLE_FREQ, /* one of the few diffs from the 5000 */ - .transceive = RIG_TRN_OFF, /* May enable later as the 5000 has an Auto Info command */ - .bank_qty = 0, - .chan_desc_sz = 0, - .str_cal = FTDX5000_STR_CAL, - .chan_list = { - { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, - { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ - RIG_CHAN_END, - }, - - .rx_range_list1 = { - /* General coverage + ham, ANT_5 is RX only antenna */ - {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "USA"}, - RIG_FRNG_END, - }, - - .tx_range_list1 = { - FRQ_RNG_HF(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), - FRQ_RNG_HF(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ - FRQ_RNG_6m(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), - FRQ_RNG_6m(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ - - RIG_FRNG_END, - }, - - .rx_range_list2 = { - {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "EUR"}, - RIG_FRNG_END, - }, - - .tx_range_list2 = { - FRQ_RNG_HF(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), - FRQ_RNG_HF(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ - FRQ_RNG_6m(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), - FRQ_RNG_6m(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ - - RIG_FRNG_END, - }, - - .tuning_steps = { - {FTDX5000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ - {FTDX5000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ - - {FTDX5000_AM_RX_MODES, Hz(100)}, /* Normal */ - {FTDX5000_AM_RX_MODES, kHz(1)}, /* Fast */ - - {FTDX5000_FM_RX_MODES, Hz(100)}, /* Normal */ - {FTDX5000_FM_RX_MODES, kHz(1)}, /* Fast */ - - RIG_TS_END, - - }, - - /* mode/filter list, .remember = order matters! */ - .filters = { - {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ - {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ - {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ - {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ - {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ - {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ - {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ - {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ - {FTDX5000_FM_RX_MODES, Hz(15000)}, /* Normal FM */ - {FTDX5000_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ - - RIG_FLT_END, - }, - - .priv = NULL, - - .rig_init = newcat_init, - .rig_cleanup = newcat_cleanup, - .rig_open = newcat_open, /* port opened */ - .rig_close = newcat_close, /* port closed */ - - .cfgparams = newcat_cfg_params, - .set_conf = newcat_set_conf, - .get_conf = newcat_get_conf, - .set_freq = newcat_set_freq, - .get_freq = newcat_get_freq, - .set_mode = newcat_set_mode, - .get_mode = newcat_get_mode, - .set_vfo = newcat_set_vfo, - .get_vfo = newcat_get_vfo, - .set_ptt = newcat_set_ptt, - .get_ptt = newcat_get_ptt, - .set_split_vfo = newcat_set_split_vfo, - .get_split_vfo = newcat_get_split_vfo, - .set_rit = newcat_set_rit, - .get_rit = newcat_get_rit, - .set_xit = newcat_set_xit, - .get_xit = newcat_get_xit, - .set_ant = newcat_set_ant, - .get_ant = newcat_get_ant, - .get_func = newcat_get_func, - .set_func = newcat_set_func, - .get_level = newcat_get_level, - .set_level = newcat_set_level, - .get_mem = newcat_get_mem, - .set_mem = newcat_set_mem, - .vfo_op = newcat_vfo_op, - .get_info = newcat_get_info, - .power2mW = newcat_power2mW, - .mW2power = newcat_mW2power, - .set_rptr_shift = newcat_set_rptr_shift, - .get_rptr_shift = newcat_get_rptr_shift, - .set_ctcss_tone = newcat_set_ctcss_tone, - .get_ctcss_tone = newcat_get_ctcss_tone, - .set_ctcss_sql = newcat_set_ctcss_sql, - .get_ctcss_sql = newcat_get_ctcss_sql, - .set_powerstat = newcat_set_powerstat, - .get_powerstat = newcat_get_powerstat, - .get_ts = newcat_get_ts, - .set_ts = newcat_set_ts, - .set_trn = newcat_set_trn, - .get_trn = newcat_get_trn, - .set_channel = newcat_set_channel, - .get_channel = newcat_get_channel, - -}; - -const struct rig_caps ftdx101d_caps = -{ - RIG_MODEL(RIG_MODEL_FTDX101D), - .model_name = "FT-DX101D", - .mfg_name = "Yaesu", - .version = NEWCAT_VER ".5", - .copyright = "LGPL", - .status = RIG_STATUS_STABLE, - .rig_type = RIG_TYPE_TRANSCEIVER, - .ptt_type = RIG_PTT_RIG, - .dcd_type = RIG_DCD_NONE, - .port_type = RIG_PORT_SERIAL, - .serial_rate_min = 4800, /* Default rate per manual */ - .serial_rate_max = 38400, - .serial_data_bits = 8, - .serial_stop_bits = 1, /* Assumed since manual makes no mention */ - .serial_parity = RIG_PARITY_NONE, - .serial_handshake = RIG_HANDSHAKE_HARDWARE, - .write_delay = FTDX5000_WRITE_DELAY, - .post_write_delay = FTDX5000_POST_WRITE_DELAY, - .timeout = 2000, - .retry = 3, - .has_get_func = FTDX5000_FUNCS, - .has_set_func = FTDX5000_FUNCS, - .has_get_level = FTDX5000_LEVELS, - .has_set_level = RIG_LEVEL_SET(FTDX5000_LEVELS), - .has_get_parm = RIG_PARM_NONE, - .has_set_parm = RIG_PARM_NONE, - .level_gran = { - [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, - [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } }, - }, - .ctcss_list = common_ctcss_list, - .dcs_list = NULL, - .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ - .attenuator = { 6, 12, 18, RIG_DBLST_END, }, - .max_rit = Hz(9999), - .max_xit = Hz(9999), - .max_ifshift = Hz(1200), - .vfo_ops = FTDX5000_VFO_OPS, - .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_LEVEL, - .transceive = RIG_TRN_OFF, /* May enable later as the 5000 has an Auto Info command */ - .bank_qty = 0, - .chan_desc_sz = 0, - .str_cal = FTDX5000_STR_CAL, - .chan_list = { - { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, - { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ - RIG_CHAN_END, - }, - - .rx_range_list1 = { - /* General coverage + ham, ANT_5 is RX only antenna */ - {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "USA"}, - RIG_FRNG_END, - }, - - .tx_range_list1 = { /* the 101DX is 100W and the MP is 200W */ - FRQ_RNG_HF(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), - FRQ_RNG_HF(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ - FRQ_RNG_6m(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), - FRQ_RNG_6m(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ - - RIG_FRNG_END, - }, - - .rx_range_list2 = { - {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "EUR"}, - RIG_FRNG_END, - }, - - .tx_range_list2 = { - FRQ_RNG_HF(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), - FRQ_RNG_HF(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ - FRQ_RNG_6m(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), - FRQ_RNG_6m(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ - FRQ_RNG_4m_REGION2(FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), - FRQ_RNG_4m_REGION2(FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ - - RIG_FRNG_END, - }, - - .tuning_steps = { - {FTDX5000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ - {FTDX5000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ - - {FTDX5000_AM_RX_MODES, Hz(100)}, /* Normal */ - {FTDX5000_AM_RX_MODES, kHz(1)}, /* Fast */ - - {FTDX5000_FM_RX_MODES, Hz(100)}, /* Normal */ - {FTDX5000_FM_RX_MODES, kHz(1)}, /* Fast */ - - RIG_TS_END, - - }, - - /* mode/filter list, .remember = order matters! */ - .filters = { - {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ - {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ - {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ - {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ - {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ - {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ - {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ - {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ - {FTDX5000_FM_RX_MODES, Hz(15000)}, /* Normal FM */ - {FTDX5000_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ - - RIG_FLT_END, - }, - - .priv = NULL, + .ext_tokens = ftdx5000_ext_tokens, + .extlevels = ftdx5000_ext_levels, + + .priv = &ftdx5000_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, @@ -544,5 +243,7 @@ const struct rig_caps ftdx101d_caps = .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, + .set_ext_level = newcat_set_ext_level, + .get_ext_level = newcat_get_ext_level, }; diff --git a/rigs/yaesu/ft5000.h b/rigs/yaesu/ft5000.h index a5ddd8a4e..db32b61b6 100644 --- a/rigs/yaesu/ft5000.h +++ b/rigs/yaesu/ft5000.h @@ -28,46 +28,38 @@ #ifndef _FT5000_H #define _FT5000_H 1 -#if 0 -#define TRUE 1 -#define FALSE 0 -#define ON TRUE -#define OFF FALSE -#endif - -#define FTDX5000_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB) +#define FTDX5000_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) /* Receiver caps */ #define FTDX5000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ - RIG_MODE_RTTY|RIG_MODE_RTTYR|\ - RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) + RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ + RIG_MODE_FM|RIG_MODE_FMN) #define FTDX5000_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FTDX5000_AM_RX_MODES (RIG_MODE_AM) -#define FTDX5000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) +#define FTDX5000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) #define FTDX5000_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) - - - /* TRX caps */ #define FTDX5000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ - RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) /* 100 W class */ + RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) /* 100 W class */ #define FTDX5000_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ /* TBC */ #define FTDX5000_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ - RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_SWR|\ + RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ - RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF) + RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ + RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|\ + RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER) /* TBC */ #define FTDX5000_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ diff --git a/rigs/yaesu/ft891.c b/rigs/yaesu/ft891.c index 0f958b322..da1997b08 100644 --- a/rigs/yaesu/ft891.c +++ b/rigs/yaesu/ft891.c @@ -38,18 +38,13 @@ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" -#include "misc.h" -#include "yaesu.h" #include "newcat.h" #include "ft891.h" #include "idx_builtin.h" /* - * ft891 rigs capabilities. - * Also this struct is READONLY! - * + * FT-891 rig capabilities */ - const struct rig_caps ft891_caps = { RIG_MODEL(RIG_MODEL_FT891), @@ -98,7 +93,6 @@ const struct rig_caps ft891_caps = .str_cal = FT891_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, - { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ RIG_CHAN_END, }, diff --git a/rigs/yaesu/ft891.h b/rigs/yaesu/ft891.h index f8c5e534c..e95401aee 100644 --- a/rigs/yaesu/ft891.h +++ b/rigs/yaesu/ft891.h @@ -28,38 +28,36 @@ #ifndef _FT891_H #define _FT891_H 1 -#define TRUE 1 -#define FALSE 0 -#define ON TRUE -#define OFF FALSE - -#define FT891_VFO_ALL (RIG_VFO_A|RIG_VFO_B) +#define FT891_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FT891_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ - RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) + RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_FM|RIG_MODE_FMN) #define FT891_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT891_AM_RX_MODES (RIG_MODE_AM) -#define FT891_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) +#define FT891_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_FMN) #define FT891_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT891_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ -#define FT891_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB | RIG_MODE_PKTUSB | RIG_MODE_PKTLSB ) /* 100 W class */ +#define FT891_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|\ + RIG_MODE_FM|RIG_MODE_FMN) /* 100 W class */ #define FT891_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ #define FT891_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_STRENGTH|\ - RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_SWR|\ + RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ - RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF) + RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ + RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|\ + RIG_LEVEL_COMP_METER|RIG_LEVEL_ID_METER) #define FT891_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ diff --git a/rigs/yaesu/ft991.c b/rigs/yaesu/ft991.c index 06e53aef3..0db7f3fcf 100644 --- a/rigs/yaesu/ft991.c +++ b/rigs/yaesu/ft991.c @@ -37,20 +37,13 @@ #include #include #include "hamlib/rig.h" -#include "bandplan.h" -#include "serial.h" -#include "misc.h" -#include "yaesu.h" #include "newcat.h" #include "ft991.h" #include "idx_builtin.h" /* - * ft991 rigs capabilities. - * Also this struct is READONLY! - * + * FT-991 rig capabilities */ - const struct rig_caps ft991_caps = { RIG_MODEL(RIG_MODEL_FT991), diff --git a/rigs/yaesu/ft991.h b/rigs/yaesu/ft991.h index e7e9aa1b3..4557d1a13 100644 --- a/rigs/yaesu/ft991.h +++ b/rigs/yaesu/ft991.h @@ -28,39 +28,37 @@ #ifndef _FT991_H #define _FT991_H 1 -#define TRUE 1 -#define FALSE 0 -#define ON TRUE -#define OFF FALSE - -#define FT991_VFO_ALL (RIG_VFO_A|RIG_VFO_B) +#define FT991_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FT991_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ - RIG_MODE_C4FM|RIG_MODE_FM|RIG_MODE_AMN) + RIG_MODE_C4FM|RIG_MODE_FM|RIG_MODE_AMN|RIG_MODE_FMN) #define FT991_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT991_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) -#define FT991_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_C4FM) +#define FT991_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN|RIG_MODE_C4FM) #define FT991_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT991_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ -#define FT991_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB | RIG_MODE_PKTUSB | RIG_MODE_PKTLSB ) /* 100 W class */ +#define FT991_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|\ + RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) /* 100 W class */ #define FT991_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ #define FT991_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_STRENGTH|\ - RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_SWR|\ + RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ - RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF) + RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ + RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|\ + RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER) #define FT991_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ diff --git a/rigs/yaesu/ftdx101.c b/rigs/yaesu/ftdx101.c new file mode 100644 index 000000000..5b6358f90 --- /dev/null +++ b/rigs/yaesu/ftdx101.c @@ -0,0 +1,244 @@ +/* + * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) + * + * ftdx101.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) + * (C) Stephane Fillod 2008-2010 + * (C) Terry Embry 2008-2009 + * (C) Mikael Nousiainen 2020 + * + * This shared library provides an API for communicating + * via serial interface to an FTDX101(D/MP) using the "CAT" interface + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "hamlib/rig.h" +#include "bandplan.h" +#include "idx_builtin.h" +#include "tones.h" +#include "newcat.h" +#include "ftdx101.h" + +cal_table_float_t yaesu_ftdx101d_swr_cal = FTDX101D_SWR_CAL; + +const struct newcat_priv_caps ftdx101d_priv_caps = +{ + .roofing_filter_count = 6, + .roofing_filters = + { + // The index must match ext level combo index + { .index = 0, .set_value = '0', .get_value = 0, .width = 12000, .optional = 0 }, + { .index = 1, .set_value = '1', .get_value = '6', .width = 12000, .optional = 0 }, + { .index = 2, .set_value = '2', .get_value = '7', .width = 3000, .optional = 0 }, + { .index = 3, .set_value = '3', .get_value = '8', .width = 1200, .optional = 1 }, + { .index = 4, .set_value = '4', .get_value = '9', .width = 600, .optional = 0 }, + { .index = 5, .set_value = '5', .get_value = 'A', .width = 300, .optional = 1 }, + } +}; + +const struct confparams ftdx101d_ext_levels[] = +{ + { + TOK_ROOFING_FILTER, + "ROOFINGFILTER", + "Roofing filter", + "Roofing filter", + NULL, + RIG_CONF_COMBO, + { .c = { .combostr = { "AUTO", "12 kHz", "3 kHz", "1.2 kHz (optional)", "600 Hz", "300 Hz (optional)", NULL } } } + }, + { RIG_CONF_END, NULL, } +}; + +int ftdx101d_ext_tokens[] = +{ + TOK_ROOFING_FILTER, TOK_BACKEND_NONE +}; + +const struct rig_caps ftdx101d_caps = +{ + RIG_MODEL(RIG_MODEL_FTDX101D), + .model_name = "FTDX101D", + .mfg_name = "Yaesu", + .version = NEWCAT_VER ".5", + .copyright = "LGPL", + .status = RIG_STATUS_STABLE, + .rig_type = RIG_TYPE_TRANSCEIVER, + .ptt_type = RIG_PTT_RIG, + .dcd_type = RIG_DCD_NONE, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 4800, + .serial_rate_max = 38400, + .serial_data_bits = 8, + .serial_stop_bits = 1, + .serial_parity = RIG_PARITY_NONE, + .serial_handshake = RIG_HANDSHAKE_HARDWARE, + .write_delay = FTDX101_WRITE_DELAY, + .post_write_delay = FTDX101_POST_WRITE_DELAY, + .timeout = 2000, + .retry = 3, + .has_get_func = FTDX101_FUNCS, + .has_set_func = FTDX101_FUNCS, + .has_get_level = FTDX101_LEVELS, + .has_set_level = RIG_LEVEL_SET(FTDX101_LEVELS), + .has_get_parm = RIG_PARM_NONE, + .has_set_parm = RIG_PARM_NONE, + .level_gran = { + [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } }, + }, + .ctcss_list = common_ctcss_list, + .dcs_list = NULL, + .preamp = { 10, 20, RIG_DBLST_END, }, + .attenuator = { 6, 12, 18, RIG_DBLST_END, }, + .max_rit = Hz(9999), + .max_xit = Hz(9999), + .max_ifshift = Hz(1200), + .vfo_ops = FTDX101_VFO_OPS, + .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_LEVEL, + .transceive = RIG_TRN_OFF, /* May enable later as the FTDX101 has an Auto Info command */ + .bank_qty = 0, + .chan_desc_sz = 0, + .swr_cal = FTDX101D_SWR_CAL, + .chan_list = { + { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, + RIG_CHAN_END, + }, + + .rx_range_list1 = { + /* General coverage + ham, ANT_5 is RX only antenna */ + {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS | RIG_ANT_5, "USA"}, + RIG_FRNG_END, + }, + + .tx_range_list1 = { /* the 101DX is 100W and the MP is 200W */ + FRQ_RNG_HF(1, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), + FRQ_RNG_HF(1, FTDX101_AM_TX_MODES, W(2), W(75), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ + FRQ_RNG_6m(1, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), + FRQ_RNG_6m(1, FTDX101_AM_TX_MODES, W(2), W(75), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ + + RIG_FRNG_END, + }, + + .rx_range_list2 = { + {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS | RIG_ANT_5, "EUR"}, + RIG_FRNG_END, + }, + + .tx_range_list2 = { + FRQ_RNG_HF(2, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), + FRQ_RNG_HF(2, FTDX101_AM_TX_MODES, W(2), W(75), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ + FRQ_RNG_6m(2, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), + FRQ_RNG_6m(2, FTDX101_AM_TX_MODES, W(2), W(75), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ + FRQ_RNG_4m_REGION2(FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), + FRQ_RNG_4m_REGION2(FTDX101_AM_TX_MODES, W(2), W(75), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ + + RIG_FRNG_END, + }, + + .tuning_steps = { + {FTDX101_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ + {FTDX101_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ + + {FTDX101_AM_RX_MODES, Hz(100)}, /* Normal */ + {FTDX101_AM_RX_MODES, kHz(1)}, /* Fast */ + + {FTDX101_FM_RX_MODES, Hz(100)}, /* Normal */ + {FTDX101_FM_RX_MODES, kHz(1)}, /* Fast */ + + RIG_TS_END, + + }, + + /* mode/filter list, remember that order matters! */ + .filters = { + {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(600)}, /* Normal CW, RTTY, PKT/USER */ + {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* Narrow CW, RTTY, PKT/USER */ + {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ + {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* Normal CW, RTTY, PKT/USER */ + {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ + {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ + {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ + {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ + {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ + {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(16000)}, /* Normal FM */ + {RIG_MODE_FMN | RIG_MODE_PKTFMN, Hz(9000)}, /* Narrow FM */ + {FTDX101_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, + + RIG_FLT_END, + }, + + .ext_tokens = ftdx101d_ext_tokens, + .extlevels = ftdx101d_ext_levels, + + .priv = &ftdx101d_priv_caps, + + .rig_init = newcat_init, + .rig_cleanup = newcat_cleanup, + .rig_open = newcat_open, /* port opened */ + .rig_close = newcat_close, /* port closed */ + + .cfgparams = newcat_cfg_params, + .set_conf = newcat_set_conf, + .get_conf = newcat_get_conf, + .set_freq = newcat_set_freq, + .get_freq = newcat_get_freq, + .set_mode = newcat_set_mode, + .get_mode = newcat_get_mode, + .set_vfo = newcat_set_vfo, + .get_vfo = newcat_get_vfo, + .set_ptt = newcat_set_ptt, + .get_ptt = newcat_get_ptt, + .set_split_vfo = newcat_set_split_vfo, + .get_split_vfo = newcat_get_split_vfo, + .set_rit = newcat_set_rit, + .get_rit = newcat_get_rit, + .set_xit = newcat_set_xit, + .get_xit = newcat_get_xit, + .set_ant = newcat_set_ant, + .get_ant = newcat_get_ant, + .get_func = newcat_get_func, + .set_func = newcat_set_func, + .get_level = newcat_get_level, + .set_level = newcat_set_level, + .get_mem = newcat_get_mem, + .set_mem = newcat_set_mem, + .vfo_op = newcat_vfo_op, + .get_info = newcat_get_info, + .power2mW = newcat_power2mW, + .mW2power = newcat_mW2power, + .set_rptr_shift = newcat_set_rptr_shift, + .get_rptr_shift = newcat_get_rptr_shift, + .set_ctcss_tone = newcat_set_ctcss_tone, + .get_ctcss_tone = newcat_get_ctcss_tone, + .set_ctcss_sql = newcat_set_ctcss_sql, + .get_ctcss_sql = newcat_get_ctcss_sql, + .set_powerstat = newcat_set_powerstat, + .get_powerstat = newcat_get_powerstat, + .get_ts = newcat_get_ts, + .set_ts = newcat_set_ts, + .set_trn = newcat_set_trn, + .get_trn = newcat_get_trn, + .set_channel = newcat_set_channel, + .get_channel = newcat_get_channel, + .set_ext_level = newcat_set_ext_level, + .get_ext_level = newcat_get_ext_level, +}; diff --git a/rigs/yaesu/ftdx101.h b/rigs/yaesu/ftdx101.h new file mode 100644 index 000000000..66be4a8a5 --- /dev/null +++ b/rigs/yaesu/ftdx101.h @@ -0,0 +1,115 @@ +/* + * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) + * + * ftdx101.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) + * (C) Stephane Fillod 2008-2010 + * (C) Mikael Nousiainen 2020 + * + * This shared library provides an API for communicating + * via serial interface to an FTDX101(D/MP) using the "CAT" interface + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +#ifndef _FTDX101_H +#define _FTDX101_H 1 + +#define FTDX101_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) + +/* Receiver caps */ + +#define FTDX101_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ + RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ + RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) + +#define FTDX101_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ + RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) +#define FTDX101_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) +#define FTDX101_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN|RIG_MODE_PKTFMN) +#define FTDX101_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ + RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) + +/* TRX caps */ + +#define FTDX101_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ + RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) /* 100 W class */ +#define FTDX101_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ + +#define FTDX101_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ + RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ + RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ + RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ + RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ + RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ + RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ + RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ + RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|\ + RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER) + +#define FTDX101_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ + RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ + RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ + RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER) + +/* TBC */ +#define FTDX101_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ + RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ + RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) + +// Based on testing with G3VPX Ian Sumner +#define FTDX101D_SWR_CAL \ + { \ + 8, \ + { \ + {0, 1.0f}, \ + {26, 1.2f}, \ + {52, 1.5f}, \ + {89, 2.0f}, \ + {126, 3.0f}, \ + {173, 4.0f}, \ + {236, 5.0f}, \ + {255, 25.0f}, \ + } \ + } + +/* + * Other features (used by rig_caps) + */ + +#define FTDX101_TX_ANTS (RIG_ANT_1|RIG_ANT_2) + +#define FTDX101_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ +#define FTDX101_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ +#define FTDX101_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ +#define FTDX101_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ +#define FTDX101_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ +#define FTDX101_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ + +/* Timing values in mS */ + +/* Delay between bytes sent + * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) + */ +#define FTDX101_WRITE_DELAY 0 + + +/* Delay sequential fast writes */ + +#define FTDX101_POST_WRITE_DELAY 5 + +#endif /* _FTDX101_H */ diff --git a/rigs/yaesu/newcat.c b/rigs/yaesu/newcat.c index 1dbf7758f..4d545fc00 100644 --- a/rigs/yaesu/newcat.c +++ b/rigs/yaesu/newcat.c @@ -34,11 +34,10 @@ #include #include /* String function definitions */ -#include /* UNIX standard function definitions */ +#include #include "hamlib/rig.h" #include "iofunc.h" -#include "serial.h" #include "misc.h" #include "cal.h" #include "newcat.h" @@ -63,7 +62,7 @@ typedef enum nc_rigid_e NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, - NC_RIGID_FT1200 = 583, + NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, @@ -94,12 +93,51 @@ typedef struct _yaesu_newcat_commands ncboolean ft101; } yaesu_newcat_commands_t; +/** + * Yaesu FT-991 S-meter scale, default for new Yaesu rigs. + * Determined by data from W6HN -- seems to be pretty linear + * + * SMeter, rig answer, %fullscale + * S0 SM0000 0 + * S2 SM0026 10 + * S4 SM0051 20 + * S6 SM0081 30 + * S7.5 SM0105 40 + * S9 SM0130 50 + * +12db SM0157 60 + * +25db SM0186 70 + * +35db SM0203 80 + * +50db SM0237 90 + * +60db SM0255 100 + * + * 114dB range over 0-255 referenced to S0 of -54dB + */ +const cal_table_t yaesu_default_str_cal = +{ + 11, + { + { 0, -54, }, // S0 + { 26, -42, }, // S2 + { 51, -30, }, // S4 + { 81, -18, }, // S6 + { 105, -9, }, // S7.5 + { 130, 0, }, // S9 + { 157, 12, }, // S9+12dB + { 186, 25, }, // S9+25dB + { 203, 35, }, // S9+35dB + { 237, 50, }, // S9+50dB + { 255, 60, }, // S9+60dB + } +}; + +/** + * First cut at generic Yaesu table, need more points probably + * based on testing by Adam M7OTP on FT-991 + */ const cal_table_float_t yaesu_default_swr_cal = { 5, { - // first cut at generic Yaesu table, need more points probably - // based on testing by Adam M7OTP on FT-991 {12, 1.0f}, {39, 1.35f}, {65, 1.5f}, @@ -108,19 +146,54 @@ const cal_table_float_t yaesu_default_swr_cal = } }; -const cal_table_float_t yaesu_ftdx101d_swr_cal = +// TODO: Provide sane defaults +const cal_table_float_t yaesu_default_alc_cal = { - 8, + 3, { - // Based on testing with G3VPX Ian Sumner - {0, 1.0f}, - {26, 1.2f}, - {52, 1.5f}, - {89, 2.0f}, - {126, 3.0f}, - {173, 4.0f}, - {236, 5.0f}, - {255, 25.0f}, + {0, 0.0f}, + {128, 1.0f}, + {255, 2.0f}, + } +}; + +// TODO: Provide sane defaults +const cal_table_float_t yaesu_default_comp_meter_cal = +{ + 2, + { + {0, 0.0f}, + {255, 1.0f}, + } +}; + +// TODO: Provide sane defaults +const cal_table_float_t yaesu_default_rfpower_meter_cal = +{ + 2, + { + {0, 0.0f}, + {255, 1.0f}, + } +}; + +// TODO: Provide sane defaults +const cal_table_float_t yaesu_default_vd_meter_cal = +{ + 2, + { + {0, 0.0f}, + {255, 1.0f}, + } +}; + +// TODO: Provide sane defaults +const cal_table_float_t yaesu_default_id_meter_cal = +{ + 2, + { + {0, 0.0f}, + {255, 1.0f}, } }; @@ -131,10 +204,10 @@ static ncboolean is_ft950; static ncboolean is_ft991; static ncboolean is_ft2000; static ncboolean is_ft9000; -static ncboolean is_ft5000; -static ncboolean is_ft1200; -static ncboolean is_ft3000; -static ncboolean is_ft101; +static ncboolean is_ftdx5000; +static ncboolean is_ftdx1200; +static ncboolean is_ftdx3000; +static ncboolean is_ftdx101; /* * Even thought this table does make a handy reference, it could be depreciated as it is not really needed. @@ -306,6 +379,9 @@ static int newcat_get_faststep(RIG *rig, ncboolean *fast_step); static int newcat_get_rigid(RIG *rig); static int newcat_get_vfo_mode(RIG *rig, vfo_t *vfo_mode); static int newcat_vfomem_toggle(RIG *rig); +static int set_roofing_filter(RIG *rig, vfo_t vfo, int index); +static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width); +static int get_roofing_filter(RIG *rig, vfo_t vfo, struct newcat_roofing_filter **roofing_filter); static ncboolean newcat_valid_command(RIG *rig, char const *const command); /* @@ -431,6 +507,8 @@ int newcat_open(RIG *rig) priv->poweron = 1; } + priv->question_mark_response_means_rejected = 0; + /* get current AI state so it can be restored */ priv->trn_state = -1; @@ -1546,7 +1624,7 @@ int newcat_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) vfo = RIG_VFO_A; tx_vfo = RIG_SPLIT_ON == split ? RIG_VFO_B : RIG_VFO_A; } - else if (is_ft101) + else if (is_ftdx101) { vfo = RIG_VFO_MAIN; tx_vfo = RIG_SPLIT_ON == split ? RIG_VFO_SUB : RIG_VFO_MAIN; @@ -1674,13 +1752,13 @@ int newcat_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) } else if (rit < 0) { - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRD%04ld%cRT1%c", cat_term, - labs(rit), cat_term, cat_term); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRD%04ld%c", cat_term, + labs(rit), cat_term); } else { - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRU%04ld%cRT1%c", cat_term, - labs(rit), cat_term, cat_term); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRU%04ld%c", cat_term, + labs(rit), cat_term); } return newcat_set_cmd(rig); @@ -1691,7 +1769,6 @@ int newcat_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv; char *retval; - //char rit_on; int err; int offset = 0; @@ -1735,14 +1812,10 @@ int newcat_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) } retval = priv->ret_data + offset; - //rit_on = retval[5]; retval[5] = '\0'; - //if (rit_on == '1') - { - // return the current offset even if turned off - *rit = (shortfreq_t) atoi(retval); - } + // return the current offset even if turned off + *rit = (shortfreq_t) atoi(retval); return RIG_OK; } @@ -1774,13 +1847,13 @@ int newcat_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) } else if (xit < 0) { - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRD%04ld%cXT1%c", cat_term, - labs(xit), cat_term, cat_term); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRD%04ld%c", cat_term, + labs(xit), cat_term); } else { - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRU%04ld%cXT1%c", cat_term, - labs(xit), cat_term, cat_term); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRU%04ld%c", cat_term, + labs(xit), cat_term); } return newcat_set_cmd(rig); @@ -1791,7 +1864,6 @@ int newcat_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv; char *retval; - //char xit_on; int err; int offset = 0; @@ -1835,14 +1907,10 @@ int newcat_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) } retval = priv->ret_data + offset; - //xit_on = retval[6]; retval[5] = '\0'; - //if (xit_on == '1') - { - // return the offset even when turned off - *xit = (shortfreq_t) atoi(retval); - } + // return the offset even when turned off + *xit = (shortfreq_t) atoi(retval); return RIG_OK; } @@ -2036,15 +2104,29 @@ int newcat_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) return -RIG_ENAVAIL; } - if (tone == 0) /* turn off ctcss */ + if (tone == 0) /* turn off ctcss */ { - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CT%c0%c", main_sub_vfo, - cat_term); + if (is_ft891 || is_ft991 || is_ftdx101) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CT%c00%c", main_sub_vfo, cat_term); + } + else + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CT%c0%c", main_sub_vfo, cat_term); + } } else { - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CN%c%02d%cCT%c2%c", - main_sub_vfo, i, cat_term, main_sub_vfo, cat_term); + if (is_ft891 || is_ft991 || is_ftdx101) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CN%c0%03d%cCT%c2%c", + main_sub_vfo, i, cat_term, main_sub_vfo, cat_term); + } + else + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CN%c%02d%cCT%c2%c", + main_sub_vfo, i, cat_term, main_sub_vfo, cat_term); + } } return newcat_set_cmd(rig); @@ -2080,8 +2162,14 @@ int newcat_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo, - cat_term); + if (is_ft891 || is_ft991 || is_ftdx101) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c0%c", cmd, main_sub_vfo, cat_term); + } + else + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo, cat_term); + } /* Get CTCSS TONE */ if (RIG_OK != (err = newcat_get_cmd(rig))) @@ -2249,10 +2337,10 @@ int newcat_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rig_id, *mwpower); break; - case NC_RIGID_FT1200: + case NC_RIGID_FTDX1200: /* 100 Watts */ *mwpower = power * 100000; - rig_debug(RIG_DEBUG_TRACE, "case FT1200 - rig_id = %d, *mwpower = %d\n", rig_id, + rig_debug(RIG_DEBUG_TRACE, "case FTDX1200 - rig_id = %d, *mwpower = %d\n", rig_id, *mwpower); break; @@ -2335,10 +2423,10 @@ int newcat_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rig_id, *power); break; - case NC_RIGID_FT1200: + case NC_RIGID_FTDX1200: /* 100 Watts */ *power = mwpower / 100000.0; - rig_debug(RIG_DEBUG_TRACE, "case FT1200 - rig_id = %d, *power = %f\n", rig_id, + rig_debug(RIG_DEBUG_TRACE, "case FTDX1200 - rig_id = %d, *power = %f\n", rig_id, *power); break; @@ -2486,12 +2574,12 @@ int newcat_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) break; case RIG_ANT_3: - if (newcat_is_rig(rig, RIG_MODEL_FT950)) /* FT2000 also */ + if (newcat_is_rig(rig, RIG_MODEL_FT950)) { return -RIG_EINVAL; } - if (newcat_is_rig(rig, RIG_MODEL_FT1200)) /* FT2000 also */ + if (newcat_is_rig(rig, RIG_MODEL_FTDX1200)) { return -RIG_EINVAL; } @@ -2505,7 +2593,7 @@ int newcat_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) return -RIG_EINVAL; } - if (newcat_is_rig(rig, RIG_MODEL_FT1200)) + if (newcat_is_rig(rig, RIG_MODEL_FTDX1200)) { return -RIG_EINVAL; } @@ -2519,7 +2607,7 @@ int newcat_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) return -RIG_EINVAL; } - if (newcat_is_rig(rig, RIG_MODEL_FT1200)) + if (newcat_is_rig(rig, RIG_MODEL_FTDX1200)) { return -RIG_EINVAL; } @@ -2643,14 +2731,29 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) return -RIG_ENAVAIL; } - scale = (is_ft450 && newcat_get_rigid(rig) == NC_RIGID_FT450D) ? 100. : 255.; - scale = is_ft891 ? 100. : scale ; - scale = is_ft950 ? 100. : scale ; - scale = is_ft1200 ? 100. : scale ; - scale = is_ft991 ? 100. : scale ; + if (is_ft950 || is_ftdx1200 || is_ftdx3000 || is_ft891 || is_ft991 || is_ftdx101) + { + scale = 100.; + } + else if (is_ft450 && newcat_get_rigid(rig) == NC_RIGID_FT450D) + { + scale = 100.; + } + else + { + scale = 255.; + } + fpf = newcat_scale_float(scale, val.f); - if (is_ft950 && fpf < 5) { fpf = 5; } // min 5 watts on FT950 + if (is_ft950 || is_ft891 || is_ft991 || is_ftdx3000 || is_ftdx101) + { + // Minimum is 5 watts on these rigs + if (fpf < 5) + { + fpf = 5; + } + } snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PC%03d%c", fpf, cat_term); break; @@ -2715,7 +2818,7 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) } } - if (is_ft101) + if (is_ftdx101) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "IS%c0%+.4d%c", main_sub_vfo, val.i, cat_term); @@ -2771,7 +2874,7 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) return -RIG_ENAVAIL; } - if (newcat_is_rig(rig, RIG_MODEL_FT1200)) + if (is_ftdx1200 || is_ftdx3000 || is_ft891 || is_ft991 || is_ftdx101) { fpf = newcat_scale_float(100, val.f); } @@ -2789,7 +2892,7 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) return -RIG_ENAVAIL; } - if (is_ft101) // new format for the command with VFO selection + if (is_ftdx101) // new format for the command with VFO selection { format = "MS0%d;"; @@ -2983,7 +3086,7 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) } scale = (is_ft950) ? 100 : 255; - scale = (is_ft1200 || is_ft101) ? 100 : scale ; + scale = (is_ftdx1200 || is_ftdx101) ? 100 : scale ; fpf = newcat_scale_float(scale, val.f); snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PL%03d%c", fpf, cat_term); break; @@ -3002,7 +3105,7 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) // consider changing this to float or to milliseconds val.i *= 100; // tenths to ms conversion - if (is_ft101) + if (is_ftdx101) { if (val.i <= 30) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD00;"); } @@ -3020,7 +3123,7 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) // this covers 300-2900 06-32 else { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%02d;", 6 + ((val.i - 300) / 100)); } } - else if (is_ft950 || is_ft450 || is_ft1200) + else if (is_ft950 || is_ft450 || is_ftdx1200) { if (val.i < 30) { @@ -3072,7 +3175,7 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) val.i = val.i * 100; rig_debug(RIG_DEBUG_TRACE, "%s: vali=%d\n", __func__, val.i); - if (is_ft950 || is_ft450 || is_ft1200) + if (is_ft950 || is_ft450 || is_ftdx1200) { if (val.i < 100) /* min is 30ms but spec is 100ms Unit Intervals */ { @@ -3086,7 +3189,7 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VD%04d%c", val.i, cat_term); } - else if (is_ft101) // new lookup table argument + else if (is_ftdx101) // new lookup table argument { rig_debug(RIG_DEBUG_TRACE, "%s: ft101 #1 val.i=%d\n", __func__, val.i); @@ -3128,8 +3231,8 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) return -RIG_ENAVAIL; } - scale = (is_ft950 || is_ft101) ? 100 : 255; - scale = (is_ft1200) ? 100 : scale; + scale = (is_ft950 || is_ftdx101) ? 100 : 255; + scale = (is_ftdx1200) ? 100 : scale; fpf = newcat_scale_float(scale, val.f); snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VG%03d%c", fpf, cat_term); break; @@ -3140,12 +3243,12 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) fpf = newcat_scale_float(100, val.f); snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%03d%c", fpf, cat_term); } - else if (is_ft101) + else if (is_ftdx101) { fpf = newcat_scale_float(100, val.f); snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AV%03d%c", fpf, cat_term); } - else if (is_ft1200) + else if (is_ftdx1200) { fpf = newcat_scale_float(100, val.f); snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX183%03d%c", fpf, cat_term); @@ -3198,6 +3301,24 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) break; + case RIG_LEVEL_MONITOR_GAIN: + if (!newcat_valid_command(rig, "ML")) + { + return -RIG_ENAVAIL; + } + + if (is_ftdx1200 || is_ftdx3000 || is_ft891 || is_ft991 || is_ftdx101) + { + fpf = newcat_scale_float(100, val.f); + } + else + { + fpf = newcat_scale_float(255, val.f); + } + + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML1%03d%c", fpf, cat_term); + break; + default: return -RIG_EINVAL; } @@ -3213,6 +3334,7 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) int err; int ret_data_len; char *retlvl; + int retlvl_len; float scale; char main_sub_vfo = '0'; @@ -3450,16 +3572,52 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RM4%c", cat_term); break; + case RIG_LEVEL_RFPOWER_METER: + if (!newcat_valid_command(rig, "RM")) + { + return -RIG_ENAVAIL; + } + + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RM5%c", cat_term); + break; + + case RIG_LEVEL_COMP_METER: + if (!newcat_valid_command(rig, "RM")) + { + return -RIG_ENAVAIL; + } + + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RM3%c", cat_term); + break; + + case RIG_LEVEL_VD_METER: + if (!newcat_valid_command(rig, "RM")) + { + return -RIG_ENAVAIL; + } + + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RM8%c", cat_term); + break; + + case RIG_LEVEL_ID_METER: + if (!newcat_valid_command(rig, "RM")) + { + return -RIG_ENAVAIL; + } + + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RM7%c", cat_term); + break; + case RIG_LEVEL_ANTIVOX: if (is_ft950) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%c", cat_term); } - else if (is_ft101) + else if (is_ftdx101) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AV%c", cat_term); } - else if (is_ft1200) + else if (is_ftdx1200) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX183%c", cat_term); } @@ -3485,6 +3643,15 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; + case RIG_LEVEL_MONITOR_GAIN: + if (!newcat_valid_command(rig, "ML")) + { + return -RIG_ENAVAIL; + } + + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML1%c", cat_term); + break; + default: return -RIG_EINVAL; } @@ -3498,32 +3665,42 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; + retlvl_len = strlen(retlvl); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; switch (level) { case RIG_LEVEL_RFPOWER: - scale = (newcat_is_rig(rig, RIG_MODEL_FT450)) && - (newcat_get_rigid(rig) == NC_RIGID_FT450D) ? 100. : 255.; - scale = newcat_is_rig(rig, RIG_MODEL_FT891) ? 100. : scale ; - scale = newcat_is_rig(rig, RIG_MODEL_FT950) ? 100. : scale ; - scale = newcat_is_rig(rig, RIG_MODEL_FT1200) ? 100. : scale ; - scale = newcat_is_rig(rig, RIG_MODEL_FT991) ? 100. : scale ; + if (is_ft950 || is_ftdx1200 || is_ftdx3000 || is_ft891 || is_ft991 || is_ftdx101) + { + scale = 100.; + } + else if (is_ft450 && newcat_get_rigid(rig) == NC_RIGID_FT450D) + { + scale = 100.; + } + else + { + scale = 255.; + } + val->f = (float)atoi(retlvl) / scale; break; case RIG_LEVEL_VOXGAIN: case RIG_LEVEL_COMP: case RIG_LEVEL_ANTIVOX: - scale = (is_ft950 || is_ft101) ? 100. : 255.; - scale = (is_ft1200 || is_ft101) ? 100. : scale ; + scale = (is_ft950 || is_ftdx101) ? 100. : 255.; + scale = (is_ftdx1200 || is_ftdx101) ? 100. : scale ; val->f = (float)atoi(retlvl) / scale; break; case RIG_LEVEL_SWR: - // some rigs like ft101dx have 6 byte return so we just truncate - retlvl[3] = 0; + if (retlvl_len > 3) { + // Some rigs like FTDX101 have 6-byte return so we just truncate + retlvl[3] = 0; + } if (rig->caps->swr_cal.size == 0) { @@ -3536,18 +3713,108 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; - case RIG_LEVEL_AF: + case RIG_LEVEL_ALC: + if (retlvl_len > 3) { + // Some rigs like FTDX101 have 6-byte return so we just truncate + retlvl[3] = 0; + } + + if (rig->caps->alc_cal.size == 0) + { + val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_alc_cal); + } + else + { + val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->alc_cal); + } + break; + + case RIG_LEVEL_RFPOWER_METER: + if (retlvl_len > 3) { + // Some rigs like FTDX101 have 6-byte return so we just truncate + retlvl[3] = 0; + } + + if (rig->caps->rfpower_meter_cal.size == 0) + { + val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_rfpower_meter_cal); + } + else + { + val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->rfpower_meter_cal); + } + break; + + case RIG_LEVEL_COMP_METER: + if (retlvl_len > 3) { + // Some rigs like FTDX101 have 6-byte return so we just truncate + retlvl[3] = 0; + } + + if (rig->caps->comp_meter_cal.size == 0) + { + val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_comp_meter_cal); + } + else + { + val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->comp_meter_cal); + } + break; + + case RIG_LEVEL_VD_METER: + if (retlvl_len > 3) { + // Some rigs like FTDX101 have 6-byte return so we just truncate + retlvl[3] = 0; + } + + if (rig->caps->vd_meter_cal.size == 0) + { + val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_vd_meter_cal); + } + else + { + val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->vd_meter_cal); + } + break; + + case RIG_LEVEL_ID_METER: + if (retlvl_len > 3) { + // Some rigs like FTDX101 have 6-byte return so we just truncate + retlvl[3] = 0; + } + + if (rig->caps->id_meter_cal.size == 0) + { + val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_id_meter_cal); + } + else + { + val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->id_meter_cal); + } + break; + case RIG_LEVEL_MICGAIN: + if (is_ftdx1200 || is_ftdx3000 || is_ft891 || is_ft991 || is_ftdx101) + { + scale = 100.; + } + else + { + scale = 255.; + } + val->f = (float)atoi(retlvl) / scale; + break; + + case RIG_LEVEL_AF: case RIG_LEVEL_RF: case RIG_LEVEL_SQL: - case RIG_LEVEL_ALC: val->f = (float)atoi(retlvl) / 255.; break; case RIG_LEVEL_BKINDL: val->i = atoi(retlvl); /* milliseconds */ - if (is_ft101) + if (is_ftdx101) { switch (val->i) { @@ -3585,35 +3852,23 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; - case RIG_LEVEL_STRENGTH: // Yaesu's return straight s-meter answers - - - if (newcat_is_rig(rig, RIG_MODEL_FT991)) + case RIG_LEVEL_STRENGTH: + if (rig->caps->str_cal.size > 0) { - // value of 0.448 determined by data from W6HN - // seems to be pretty linear - // SMeter, rig answer, %fullscale - // S0 SM0000 0 - // S2 SM0026 10 - // S4 SM0051 20 - // S6 SM0081 30 - // S7.5 SM0105 40 - // S9 SM0130 50 - // +12db SM0157 60 - // +25db SM0186 70 - // +35db SM0203 80 - // +50db SM0237 90 - // +60db SM0255 100 - // 114dB range over 0-255 referenced to S0 of -54dB - val->i = atoi(retlvl) * (114.0 / 255.0) - 54; + val->i = round(rig_raw2val(atoi(retlvl), &rig->caps->str_cal)); + break; } - else // some Yaesu's return straight s-meter answers + + if (is_ftdx1200 || is_ftdx3000 || is_ftdx5000 || is_ft891 || is_ft991 || is_ftdx101) + { + val->i = round(rig_raw2val(atoi(retlvl), &yaesu_default_str_cal)); + } + else // some Yaesu rigs return straight s-meter answers { // Return dbS9 -- does >S9 mean 10dB increments? If not, add to rig driver if (val->i > 0) { val->i = (atoi(retlvl) - 9) * 10; } else { val->i = (atoi(retlvl) - 9) * 6; } // Return dbS9 does >S9 mean 10dB increments? } - break; case RIG_LEVEL_RAWSTR: @@ -3657,7 +3912,7 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) case RIG_LEVEL_VOXDELAY: val->i = atoi(retlvl); - if (is_ft101) + if (is_ftdx101) { switch (val->i) { @@ -3753,6 +4008,18 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) val->i = atoi(retlvl) * 10; break; + case RIG_LEVEL_MONITOR_GAIN: + if (is_ftdx1200 || is_ftdx3000 || is_ft891 || is_ft991 || is_ftdx101) + { + scale = 100.; + } + else + { + scale = 255.; + } + val->f = (float)atoi(retlvl) / scale; + break; + default: return -RIG_EINVAL; } @@ -3864,8 +4131,15 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) return -RIG_ENAVAIL; } - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "LK%d%c", status ? 1 : 0, - cat_term); + if (is_ftdx1200 || is_ftdx3000 || is_ftdx5000 || is_ftdx101) + { + // These rigs can lock Main/Sub VFO dials individually + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "LK%d%c", status ? 7 : 4, cat_term); + } + else + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "LK%d%c", status ? 1 : 0, cat_term); + } break; case RIG_FUNC_MON: @@ -3916,7 +4190,7 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) return -RIG_ENAVAIL; } - if (is_ft101 || is_ft5000) + if (is_ftdx1200 || is_ftdx3000 || is_ft891 || is_ft991 || is_ftdx101) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR0%d%c", status ? 1 : 0, cat_term); @@ -3946,7 +4220,7 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) } // some rigs use AC02 to actually start tuning - if (status == 1 && (is_ft101 || is_ft5000)) { status = 2; } + if (status == 1 && (is_ftdx101 || is_ftdx5000)) { status = 2; } snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AC00%d%c", status == 0 ? 0 : status, @@ -3986,6 +4260,7 @@ int newcat_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv; int err; int ret_data_len; + int last_char_index; char *retfunc; char main_sub_vfo = '0'; @@ -4121,7 +4396,7 @@ int newcat_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) return -RIG_ENAVAIL; } - if (is_ft101 || is_ft5000) + if (is_ftdx1200 || is_ftdx3000 || is_ft891 || is_ft991 || is_ftdx101) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR0%c", cat_term); } @@ -4184,6 +4459,8 @@ int newcat_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; + last_char_index = strlen(retfunc) - 1; + rig_debug(RIG_DEBUG_TRACE, "%s: retfunc='%s'\n", __func__, retfunc); switch (func) @@ -4193,19 +4470,27 @@ int newcat_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) break; case RIG_FUNC_COMP: + *status = (retfunc[0] == '0') ? 0 : 1; + break; - // future Yaesu's may use the new command format - // so we do this check here instead of the back end - // only need to add the "|| is_XXX" here - if (is_ft101) { *status = (retfunc[1] == '0') ? 0 : 1; } - else { *status = (retfunc[0] == '0') ? 0 : 1; } - + case RIG_FUNC_MON: + // The number of digits varies by rig, but the last digit indicates the status always + *status = (retfunc[last_char_index] == '0') ? 0 : 1; + break; + case RIG_FUNC_LOCK: + if (is_ftdx1200 || is_ftdx3000 || is_ftdx5000 || is_ftdx101) + { + // These rigs can lock Main/Sub VFO dials individually + *status = (retfunc[0] == '0' || retfunc[0] == '4') ? 0 : 1; + } + else + { + *status = (retfunc[0] == '0') ? 0 : 1; + } break; case RIG_FUNC_ANF: case RIG_FUNC_FBKIN: - case RIG_FUNC_LOCK: - case RIG_FUNC_MON: case RIG_FUNC_NB: case RIG_FUNC_NR: case RIG_FUNC_VOX: @@ -4260,17 +4545,45 @@ int newcat_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - return -RIG_ENAVAIL; -} + switch (token) + { + case TOK_ROOFING_FILTER: + return set_roofing_filter(rig, vfo, val.i); + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %s\n", __func__, rig_strlevel(token)); + return -RIG_EINVAL; + } +} int newcat_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val) { + int retval; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - return -RIG_ENAVAIL; -} + switch (token) + { + case TOK_ROOFING_FILTER: + { + struct newcat_roofing_filter *roofing_filter; + retval = get_roofing_filter(rig, vfo, &roofing_filter); + if (retval != RIG_OK) + { + return retval; + } + val->i = roofing_filter->index; + break; + } + + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %s\n", __func__, rig_strlevel(token)); + return -RIG_EINVAL; + } + + return RIG_OK; +} int newcat_set_ext_parm(RIG *rig, token_t token, value_t val) { @@ -4408,7 +4721,9 @@ int newcat_set_mem(RIG *rig, vfo_t vfo, int ch) rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); + priv->question_mark_response_means_rejected = 1; err = newcat_set_cmd(rig); + priv->question_mark_response_means_rejected = 0; if (err != RIG_OK) { @@ -4771,7 +5086,9 @@ int newcat_set_channel(RIG *rig, const channel_t *chan) rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Set Memory Channel */ + priv->question_mark_response_means_rejected = 1; err = newcat_set_cmd(rig); + priv->question_mark_response_means_rejected = 0; if (err != RIG_OK) { @@ -4834,7 +5151,10 @@ int newcat_get_channel(RIG *rig, channel_t *chan, int read_only) /* Get Memory Channel */ - if (RIG_OK != (err = newcat_get_cmd(rig))) + priv->question_mark_response_means_rejected = 1; + err = newcat_get_cmd(rig); + priv->question_mark_response_means_rejected = 0; + if (RIG_OK != err) { if (-RIG_ERJCTED == err) { @@ -5014,23 +5334,21 @@ ncboolean newcat_valid_command(RIG *rig, char const *const command) is_ft991 = newcat_is_rig(rig, RIG_MODEL_FT991); is_ft2000 = newcat_is_rig(rig, RIG_MODEL_FT2000); is_ft9000 = newcat_is_rig(rig, RIG_MODEL_FT9000); - is_ft5000 = newcat_is_rig(rig, RIG_MODEL_FTDX5000); - is_ft1200 = newcat_is_rig(rig, RIG_MODEL_FT1200); - is_ft3000 = newcat_is_rig(rig, RIG_MODEL_FTDX3000); - is_ft101 = newcat_is_rig(rig, RIG_MODEL_FTDX101D); - + is_ftdx5000 = newcat_is_rig(rig, RIG_MODEL_FTDX5000); + is_ftdx1200 = newcat_is_rig(rig, RIG_MODEL_FTDX1200); + is_ftdx3000 = newcat_is_rig(rig, RIG_MODEL_FTDX3000); + is_ftdx101 = newcat_is_rig(rig, RIG_MODEL_FTDX101D); if (!is_ft450 && !is_ft950 && !is_ft891 && !is_ft991 && !is_ft2000 - && !is_ft5000 && !is_ft9000 && !is_ft1200 && !is_ft3000 && !is_ft101) + && !is_ftdx5000 && !is_ft9000 && !is_ftdx1200 && !is_ftdx3000 && !is_ftdx101) { - rig_debug(RIG_DEBUG_ERR, "%s: '%s' is unknown\n", - __func__, caps->model_name); + rig_debug(RIG_DEBUG_ERR, "%s: '%s' is unknown\n", __func__, caps->model_name); return FALSE; } /* * Make sure the command is known, and then check to make sure - * is it valud for the rig. + * is it valid for the rig. */ search_low = 0; @@ -5077,7 +5395,7 @@ ncboolean newcat_valid_command(RIG *rig, char const *const command) { return TRUE; } - else if (is_ft5000 && valid_commands[search_index].ft5000) + else if (is_ftdx5000 && valid_commands[search_index].ft5000) { return TRUE; } @@ -5085,15 +5403,15 @@ ncboolean newcat_valid_command(RIG *rig, char const *const command) { return TRUE; } - else if (is_ft1200 && valid_commands[search_index].ft1200) + else if (is_ftdx1200 && valid_commands[search_index].ft1200) { return TRUE; } - else if (is_ft3000 && valid_commands[search_index].ft3000) + else if (is_ftdx3000 && valid_commands[search_index].ft3000) { return TRUE; } - else if (is_ft101 && valid_commands[search_index].ft101) + else if (is_ftdx101 && valid_commands[search_index].ft101) { return TRUE; } @@ -5182,14 +5500,14 @@ int newcat_set_tx_vfo(RIG *rig, vfo_t tx_vfo) if (newcat_is_rig(rig, RIG_MODEL_FT950) || newcat_is_rig(rig, RIG_MODEL_FT2000) || newcat_is_rig(rig, RIG_MODEL_FTDX5000) || - newcat_is_rig(rig, RIG_MODEL_FT1200) || + newcat_is_rig(rig, RIG_MODEL_FTDX1200) || newcat_is_rig(rig, RIG_MODEL_FT991) || newcat_is_rig(rig, RIG_MODEL_FTDX3000)) { p1 = p1 + 2; /* use non-Toggle commands */ } - if (is_ft101) + if (is_ftdx101) { // what other Yaeus rigs should be using this? // The DX101D returns FT0 when in split and not transmitting @@ -5216,7 +5534,7 @@ int newcat_get_tx_vfo(RIG *rig, vfo_t *tx_vfo) vfo_t vfo_mode; char const *command = "FT"; - if (is_ft101) + if (is_ftdx101) { // what other Yaeus rigs should be using this? // The DX101D returns FT0 when in split and not transmitting @@ -5772,7 +6090,7 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) return -RIG_EINVAL; } // end switch(mode) } // end is_ft991 - else if (is_ft1200) + else if (is_ftdx1200) { switch (mode) { @@ -5850,11 +6168,9 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) default: return -RIG_EINVAL; } // end switch(mode) - } // end is_ft1200 - else if (is_ft101) + } // end is_ftdx1200 + else if (is_ftdx101) { - int roof_width; - switch (mode) { case RIG_MODE_PKTUSB: @@ -5913,22 +6229,11 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) else { w = 23; } // 4000Hz } // end switch(mode) - // set roofing filter to allow for requested bandwidth - // widths of 3 and 5 are optional so won't do them - if (width <= 600) { roof_width = 4; } - else if (width <= 3000) { roof_width = 2; } - else { roof_width = 1; } - - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%1d%c", main_sub_vfo, - roof_width, - cat_term); - - if (RIG_OK != (err = newcat_set_cmd(rig))) + if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { return err; } - - } // end is_ft101 + } // end is_ftdx101 else { // FT450, FT2000, FT5000, FT9000 @@ -5977,7 +6282,7 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) /* end else */ - if (is_ft101) + if (is_ftdx101) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SH%c0%02d;", main_sub_vfo, w); } @@ -5992,31 +6297,146 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) return newcat_set_cmd(rig); } -static char get_roofing_filter(RIG *rig, vfo_t vfo) +static int set_roofing_filter(RIG *rig, vfo_t vfo, int index) { struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv; - char roofing_filter; + struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv; + struct newcat_roofing_filter *roofing_filters; char main_sub_vfo = '0'; - char rf_vfo = 'X'; + char roofing_filter_choice = 0; int err; - int n; + int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + if (priv_caps == NULL) + { + return -RIG_ENAVAIL; + } + + roofing_filters = priv_caps->roofing_filters; + if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%c", main_sub_vfo, - cat_term); + if (!newcat_valid_command(rig, "RF")) + { + return -RIG_ENAVAIL; + } + + for (i = 0; roofing_filters[i].index >= 0; i++) + { + struct newcat_roofing_filter *current_filter = &roofing_filters[i]; + char set_value = current_filter->set_value; + if (set_value == 0) + { + continue; + } + + roofing_filter_choice = set_value; + + if (current_filter->index == index) + { + break; + } + } + + if (roofing_filter_choice == 0) + { + return -RIG_EINVAL; + } + + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%c%c", main_sub_vfo, roofing_filter_choice, cat_term); + + priv->question_mark_response_means_rejected = 1; + err = newcat_set_cmd(rig); + priv->question_mark_response_means_rejected = 0; + + if (RIG_OK != err) + { + return err; + } + + return RIG_OK; +} + +static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width) +{ + struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv; + int index = -1; + int i; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + if (priv_caps == NULL) + { + return -RIG_ENAVAIL; + } + + for (i = 0; i < priv_caps->roofing_filter_count; i++) + { + struct newcat_roofing_filter *current_filter = &priv_caps->roofing_filters[i]; + char set_value = current_filter->set_value; + + // Skip get-only values and optional filters + if (set_value == 0 || current_filter->optional) + { + continue; + } + + // The last filter is always the narrowest + if (current_filter->width < width) + { + break; + } + + index = current_filter->index; + } + + if (index < 0) + { + return -RIG_EINVAL; + } + + return set_roofing_filter(rig, vfo, index); +} + +static int get_roofing_filter(RIG *rig, vfo_t vfo, struct newcat_roofing_filter **roofing_filter) +{ + struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv; + struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv; + struct newcat_roofing_filter *roofing_filters; + char roofing_filter_choice; + char main_sub_vfo = '0'; + char rf_vfo = 'X'; + int err; + int n; + int i; + + rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); + + if (priv_caps == NULL) + { + return -RIG_ENAVAIL; + } + + roofing_filters = priv_caps->roofing_filters; + + if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) + { + main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; + } + + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%c", main_sub_vfo, cat_term); if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } - n = sscanf(priv->ret_data, "RF%c%c", &rf_vfo, &roofing_filter); + n = sscanf(priv->ret_data, "RF%c%c", &rf_vfo, &roofing_filter_choice); if (n != 2) { @@ -6026,7 +6446,21 @@ static char get_roofing_filter(RIG *rig, vfo_t vfo) return -RIG_EPROTO; } - return roofing_filter; + for (i = 0; i < priv_caps->roofing_filter_count; i++) + { + struct newcat_roofing_filter *current_filter = &roofing_filters[i]; + if (current_filter->get_value == roofing_filter_choice) + { + *roofing_filter = current_filter; + return RIG_OK; + } + } + + rig_debug(RIG_DEBUG_ERR, + "%s: Expected a valid roofing filter but got %c from '%s'\n", __func__, + roofing_filter_choice, priv->ret_data); + + return RIG_EPROTO; } int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) @@ -6111,8 +6545,8 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) rig_debug(RIG_DEBUG_TRACE, "%s: w=%d\n", __func__, w); - // ft950 and ft1200 overlap so we'll combine them - if (is_ft950 || is_ft1200) + // ft950 and ftdx1200 overlap so we'll combine them + if (is_ft950 || is_ftdx1200) { if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) { @@ -6222,7 +6656,7 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) case 20: *width = 3000; break; - // 21+ is for the FT1200 + // 21+ is for the FTDX1200 case 21: *width = 3200; break; case 22: *width = 3400; break; @@ -6247,7 +6681,7 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) return -RIG_EINVAL; } /* end switch(mode) */ - } /* end if FT950 FT1200 */ + } /* end if FT950 FTDX1200 */ else if (newcat_is_rig(rig, RIG_MODEL_FT991)) { @@ -6382,30 +6816,17 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) else if (newcat_is_rig(rig, RIG_MODEL_FTDX101D)) { - rig_debug(RIG_DEBUG_TRACE, "%s: is_ft101 w=%d, mode=%s\n", __func__, w, + rig_debug(RIG_DEBUG_TRACE, "%s: is_ftdx101 w=%d, mode=%s\n", __func__, w, rig_strrmode(mode)); if (w == 0) // then we need to know the roofing filter { - char roofing_filter = get_roofing_filter(rig, vfo); + struct newcat_roofing_filter *roofing_filter; + int err = get_roofing_filter(rig, vfo, &roofing_filter); - switch (roofing_filter) + if (err == RIG_OK) { - case '6': *width = 12000; break; - - case '7': *width = 3000; break; - - case '8': *width = 1200; break; - - case '9': *width = 600; break; - - case 'A': *width = 300; break; - - default: - rig_debug(RIG_DEBUG_ERR, - "%s: Expected roofing filter 6,7,8,9,A but got %c from '%s'\n", __func__, - roofing_filter, priv->ret_data); - return RIG_OK; + *width = roofing_filter->width; } } @@ -6941,6 +7362,13 @@ int newcat_get_cmd(RIG *rig) break; /* retry */ case '?': + if (priv->question_mark_response_means_rejected) + { + /* Some commands, like MR and MC return "?;" when choosing a channel that doesn't exist */ + rig_debug(RIG_DEBUG_ERR, "%s: Command rejected: '%s'\n", __func__, priv->cmd_str); + return -RIG_ERJCTED; + } + /* Rig busy wait please */ rig_debug(RIG_DEBUG_ERR, "%s: Rig busy\n", __func__); rc = -RIG_BUSBUSY; @@ -7064,7 +7492,14 @@ int newcat_set_cmd(RIG *rig) break; /* retry */ case '?': - /* Rig busy wait please */ + if (priv->question_mark_response_means_rejected) + { + /* Some commands, like MR and MC return "?;" when choosing a channel that doesn't exist */ + rig_debug(RIG_DEBUG_ERR, "%s: Command rejected: '%s'\n", __func__, priv->cmd_str); + return -RIG_ERJCTED; + } + + /* Rig busy wait please */ rig_debug(RIG_DEBUG_WARN, "%s: Rig busy - retrying\n", __func__); /* read the verify command reply */ diff --git a/rigs/yaesu/newcat.h b/rigs/yaesu/newcat.h index eb11f7147..6862f639f 100644 --- a/rigs/yaesu/newcat.h +++ b/rigs/yaesu/newcat.h @@ -50,7 +50,7 @@ typedef char ncboolean; /* shared function version */ -#define NEWCAT_VER "20201025" +#define NEWCAT_VER "20201026" /* Hopefully large enough for future use, 512 chars plus '\0' */ #define NEWCAT_DATA_LEN 513 @@ -72,12 +72,34 @@ typedef char ncboolean; extern const struct confparams newcat_cfg_params[]; /* - * future - private data - * - * FIXME: Does this need to be exposed to the application/frontend through - * rig_caps.priv? I'm guessing not since it's private to the backend. -N0NB + * Private caps for newcat rigs */ +#define NEWCAT_ROOFING_FILTER_COUNT 12 + +struct newcat_roofing_filter +{ + /* Index of the roofing filter in the ext level combo */ + int index; + /* Value to set the selected roofing filter, must be 0 for a get-only choice */ + char set_value; + /* Value returned by the rig for this roofing filter, must be 0 for a set-only choice */ + char get_value; + /* Width of the filter in Hz */ + int width; + /* 0 = Always available, 1 = Optional filter */ + int optional; +}; + +struct newcat_priv_caps +{ + int roofing_filter_count; + struct newcat_roofing_filter roofing_filters[NEWCAT_ROOFING_FILTER_COUNT]; +}; + +/* + * Private state for newcat rigs + */ struct newcat_priv_data { unsigned int @@ -96,10 +118,10 @@ struct newcat_priv_data struct timespec cache_start; char last_if_response[NEWCAT_DATA_LEN]; int poweron; /* to prevent powering on more than once */ - int has_bs_cmd; // used to restore band memory */ + int has_bs_cmd; /* used to restore band memory */ + int question_mark_response_means_rejected; /* the question mark response has multiple meanings */ }; - /* * Functions considered to be Stable: * @@ -196,5 +218,11 @@ rmode_t newcat_rmode(char mode); char newcat_modechar(rmode_t rmode); rmode_t newcat_rmode_width(RIG *rig, vfo_t vfo, char mode, pbwidth_t *width); +int newcat_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val); +int newcat_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val); + +#define TOKEN_BACKEND(t) (t) + +#define TOK_ROOFING_FILTER TOKEN_BACKEND(100) #endif /* _NEWCAT_H */ diff --git a/rigs/yaesu/yaesu.c b/rigs/yaesu/yaesu.c index 7a96a5b26..f21b9f462 100644 --- a/rigs/yaesu/yaesu.c +++ b/rigs/yaesu/yaesu.c @@ -107,7 +107,7 @@ DECLARE_INITRIG_BACKEND(yaesu) rig_register(&frg9600_caps); rig_register(&vr5000_caps); rig_register(&vx1700_caps); - rig_register(&ft1200_caps); + rig_register(&ftdx1200_caps); rig_register(&ft991_caps); rig_register(&ft891_caps); rig_register(&ft847uni_caps); diff --git a/rigs/yaesu/yaesu.h b/rigs/yaesu/yaesu.h index 8a5e51653..fc407f71b 100644 --- a/rigs/yaesu/yaesu.h +++ b/rigs/yaesu/yaesu.h @@ -78,7 +78,7 @@ extern const struct rig_caps frg8800_caps; extern const struct rig_caps frg9600_caps; extern const struct rig_caps vr5000_caps; extern const struct rig_caps vx1700_caps; -extern const struct rig_caps ft1200_caps; +extern const struct rig_caps ftdx1200_caps; extern const struct rig_caps ft847uni_caps; extern const struct rig_caps ftdx101d_caps; extern const struct rig_caps ft818_caps; diff --git a/src/misc.c b/src/misc.c index a8c81175e..b867c9f39 100644 --- a/src/misc.c +++ b/src/misc.c @@ -328,6 +328,7 @@ static struct { RIG_MODE_PKTLSB, "PKTLSB" }, { RIG_MODE_PKTUSB, "PKTUSB" }, { RIG_MODE_PKTFM, "PKTFM" }, + { RIG_MODE_PKTFMN, "PKTFMN" }, { RIG_MODE_ECSSUSB, "ECSSUSB" }, { RIG_MODE_ECSSLSB, "ECSSLSB" }, { RIG_MODE_FAX, "FAX" },