kopia lustrzana https://github.com/Hamlib/Hamlib
				
				
				
			
		
			
				
	
	
		
			802 wiersze
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			802 wiersze
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
| /*
 | |
|  * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com)
 | |
|  *
 | |
|  * ft757gx.c - (C) Stephane Fillod 2004
 | |
|  *             (C) Nate Bargmann 2008
 | |
|  *
 | |
|  * This shared library provides an API for communicating
 | |
|  * via serial interface to an FT-757GX/FT-757GXII using the
 | |
|  * "CAT" interface box (FIF-232C) or similar.
 | |
|  *
 | |
|  *
 | |
|  *   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
 | |
|  *
 | |
|  */
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * TODO
 | |
|  *
 | |
|  * 1. Allow cached reads
 | |
|  * 2. set_mem/get_mem, vfo_op, get_channel, set_split/get_split,
 | |
|  *    set_func/get_func
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #include "config.h"
 | |
| #endif
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <string.h>     /* String function definitions */
 | |
| #include <unistd.h>     /* UNIX standard function definitions */
 | |
| 
 | |
| #include <hamlib/rig.h>
 | |
| #include "serial.h"
 | |
| #include "misc.h"
 | |
| #include "yaesu.h"
 | |
| #include "ft757gx.h"
 | |
| 
 | |
| /* Private helper function prototypes */
 | |
| static int ft757_get_update_data(RIG *rig);
 | |
| static int mode2rig(RIG *rig, rmode_t mode, pbwidth_t width);
 | |
| static int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width);
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * future - private data
 | |
|  *
 | |
|  */
 | |
| struct ft757_priv_data {
 | |
|     unsigned char pacing;           /* pacing value */
 | |
|     unsigned int read_update_delay; /* depends on pacing value */
 | |
|     unsigned char current_vfo;      /* active VFO from last cmd , can be either RIG_VFO_A or RIG_VFO_B only */
 | |
|     unsigned char update_data[FT757GX_STATUS_UPDATE_DATA_LENGTH]; /* returned data */
 | |
|     double curfreq; /* for fake get_freq on 757G */
 | |
|     char fakefreq; /* 0=no fake, 1=fake get freq */
 | |
| };
 | |
| 
 | |
| #define TOKEN_BACKEND(t) (t)
 | |
| #define TOK_FAKEFREQ TOKEN_BACKEND(1)
 | |
| 
 | |
| const struct confparams ft757gx_cfg_params[] = {
 | |
|         { TOK_FAKEFREQ, "fakefreq", "Fake get-freq", "Fake getting freq",
 | |
|                         "0", RIG_CONF_CHECKBUTTON
 | |
|         },
 | |
|         { RIG_CONF_END, NULL, }
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * ft757gx rig capabilities.
 | |
|  * Also this struct is READONLY!
 | |
|  */
 | |
| const struct rig_caps ft757gx_caps = {
 | |
|     .rig_model =        RIG_MODEL_FT757,
 | |
|     .model_name =       "FT-757GX",
 | |
|     .mfg_name =         "Yaesu",
 | |
|     .version =          "0.5.0",
 | |
|     .copyright =        "LGPL",
 | |
|     .status =           RIG_STATUS_BETA,
 | |
|     .rig_type =         RIG_TYPE_MOBILE,
 | |
|     .ptt_type =         RIG_PTT_NONE,
 | |
|     .dcd_type =         RIG_DCD_NONE,
 | |
|     .port_type =        RIG_PORT_SERIAL,
 | |
|     .serial_rate_min =  4800,
 | |
|     .serial_rate_max =  4800,
 | |
|     .serial_data_bits = 8,
 | |
|     .serial_stop_bits = 2,
 | |
|     .serial_parity =    RIG_PARITY_NONE,
 | |
|     .serial_handshake = RIG_HANDSHAKE_NONE,
 | |
|     .write_delay =      FT757GX_WRITE_DELAY,
 | |
|     .post_write_delay = FT757GX_POST_WRITE_DELAY,
 | |
|     .timeout =          FT757GX_DEFAULT_READ_TIMEOUT,
 | |
|     .retry =            10,
 | |
|     .has_get_func =     RIG_FUNC_NONE,
 | |
|     .has_set_func =     RIG_FUNC_NONE,
 | |
|     .has_get_level =    RIG_LEVEL_NONE,
 | |
|     .has_set_level =    RIG_LEVEL_NONE,
 | |
|     .has_get_parm =     RIG_PARM_NONE,
 | |
|     .has_set_parm =     RIG_PARM_NONE,
 | |
|     .ctcss_list =       NULL,
 | |
|     .dcs_list =         NULL,
 | |
|     .preamp =           { RIG_DBLST_END, },
 | |
|     .attenuator =       { RIG_DBLST_END, },
 | |
|     .max_rit =          Hz(9999),
 | |
|     .max_xit =          Hz(0),
 | |
|     .max_ifshift =      Hz(0),
 | |
|     .targetable_vfo =   0,
 | |
|     .transceive =       RIG_TRN_OFF,
 | |
|     .bank_qty =         0,
 | |
|     .chan_desc_sz =     0,
 | |
|     .chan_list =        { RIG_CHAN_END, },  /* FIXME: memory channel list:20 */
 | |
| 
 | |
|     .rx_range_list1 =   { RIG_FRNG_END, },  /* FIXME: enter region 1 setting */
 | |
| 
 | |
|     .tx_range_list1 =   { RIG_FRNG_END, },
 | |
| 
 | |
|     .rx_range_list2 =   { { .start = kHz(500), .end = 29999990,
 | |
|         .modes = FT757GX_ALL_RX_MODES,.low_power = -1,.high_power = -1},
 | |
|         RIG_FRNG_END, }, /* rx range */
 | |
| 
 | |
|     .tx_range_list2 =   { {kHz(1500),1999900,FT757GX_ALL_TX_MODES,.low_power = 5000,.high_power = 100000},
 | |
| 
 | |
|         {.start = kHz(3500),3999900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = kHz(7000),7499900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = MHz(10),10499900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = MHz(14),14499900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = MHz(18),18499900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = MHz(21),21499900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = kHz(24500),24999900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = MHz(28),29999900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         RIG_FRNG_END, },
 | |
| 
 | |
| 
 | |
|     .tuning_steps =     {
 | |
|         {FT757GX_ALL_RX_MODES,10},
 | |
|         {FT757GX_ALL_RX_MODES,100},
 | |
|         RIG_TS_END,
 | |
|     },
 | |
| 
 | |
|     /* mode/filter list, .remember =  order matters! */
 | |
|     .filters =          {
 | |
|         RIG_FLT_END,
 | |
|     },
 | |
| 
 | |
| 
 | |
|     .priv =             NULL,               /* private data */
 | |
| 
 | |
|     .rig_init =         ft757_init,
 | |
|     .rig_cleanup =      ft757_cleanup,
 | |
|     .rig_open =         ft757_open,         /* port opened */
 | |
|     .rig_close =        NULL,               /* port closed */
 | |
| 
 | |
|     .set_freq =         ft757_set_freq,     /* set freq */
 | |
|     .get_freq =         ft757gx_get_freq,   /* get freq */
 | |
|     .set_mode =         NULL,               /* set mode */
 | |
|     .get_mode =         NULL,               /* get mode */
 | |
|     .set_vfo =          ft757_set_vfo,      /* set vfo */
 | |
| 
 | |
|     .set_ptt =          NULL,               /* set ptt */
 | |
|     .get_ptt =          NULL,               /* get ptt */
 | |
| 
 | |
|     .cfgparams = ft757gx_cfg_params,
 | |
|     .set_conf = ft757gx_set_conf,
 | |
|     .get_conf = ft757gx_get_conf
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * ft757gx2 rig capabilities.
 | |
|  * Also this struct is READONLY!
 | |
|  */
 | |
| const struct rig_caps ft757gx2_caps = {
 | |
|     .rig_model =        RIG_MODEL_FT757GXII,
 | |
|     .model_name =       "FT-757GXII",
 | |
|     .mfg_name =         "Yaesu",
 | |
|     .version =          "0.4",
 | |
|     .copyright =        "LGPL",
 | |
|     .status =           RIG_STATUS_STABLE,
 | |
|     .rig_type =         RIG_TYPE_MOBILE,
 | |
|     .ptt_type =         RIG_PTT_SERIAL_DTR,     /* CAT port pin 4 per manual */
 | |
|     .dcd_type =         RIG_DCD_NONE,
 | |
|     .port_type =        RIG_PORT_SERIAL,
 | |
|     .serial_rate_min =  4800,
 | |
|     .serial_rate_max =  4800,
 | |
|     .serial_data_bits = 8,
 | |
|     .serial_stop_bits = 2,
 | |
|     .serial_parity =    RIG_PARITY_NONE,
 | |
|     .serial_handshake = RIG_HANDSHAKE_NONE,
 | |
|     .write_delay =      FT757GX_WRITE_DELAY,
 | |
|     .post_write_delay = FT757GX_POST_WRITE_DELAY,
 | |
|     .timeout =          FT757GX_DEFAULT_READ_TIMEOUT,
 | |
|     .retry =            10,
 | |
|     .has_get_func =     RIG_FUNC_LOCK,
 | |
|     .has_set_func =     RIG_FUNC_LOCK,
 | |
|     .has_get_level =    RIG_LEVEL_RAWSTR,
 | |
|     .has_set_level =    RIG_LEVEL_NONE,
 | |
|     .has_get_parm =     RIG_PARM_NONE,
 | |
|     .has_set_parm =     RIG_PARM_NONE,
 | |
|     .vfo_ops =          RIG_OP_CPY | RIG_OP_FROM_VFO | RIG_OP_TO_VFO |
 | |
|                         RIG_OP_UP | RIG_OP_DOWN,
 | |
|     .ctcss_list =       NULL,
 | |
|     .dcs_list =         NULL,
 | |
|     .preamp =           { RIG_DBLST_END, },
 | |
|     .attenuator =       { RIG_DBLST_END, },
 | |
|     .max_rit =          Hz(0),
 | |
|     .max_xit =          Hz(0),
 | |
|     .max_ifshift =      Hz(0),
 | |
|     .targetable_vfo =   0,
 | |
|     .transceive =       RIG_TRN_OFF,
 | |
|     .bank_qty =         0,
 | |
|     .chan_desc_sz =     0,
 | |
|     .chan_list =        {
 | |
|         {   0,  9, RIG_MTYPE_MEM, FT757_MEM_CAP },
 | |
|         RIG_CHAN_END
 | |
|     },
 | |
| 
 | |
|     .rx_range_list1 =   { RIG_FRNG_END, },    /* FIXME: enter region 1 setting */
 | |
| 
 | |
|     .tx_range_list1 =   { RIG_FRNG_END, },
 | |
| 
 | |
|     .rx_range_list2 =   { { .start = kHz(150), .end = 29999990,
 | |
|         .modes =            FT757GX_ALL_RX_MODES,.low_power = -1,.high_power = -1},
 | |
|         RIG_FRNG_END, }, /* rx range */
 | |
| 
 | |
|     /* FIXME: 10m is "less" and AM is 25W carrier */
 | |
|     .tx_range_list2 =    { {kHz(1500),1999900,FT757GX_ALL_TX_MODES,.low_power = 5000,.high_power = 100000},
 | |
| 
 | |
|         {.start = kHz(3500),3999900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = kHz(7000),7499900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = MHz(10),10499900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = MHz(14),14499900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = MHz(18),18499900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = MHz(21),21499900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = kHz(24500),24999900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         {.start = MHz(28),29999900,FT757GX_ALL_TX_MODES,5000,100000},
 | |
| 
 | |
|         RIG_FRNG_END, },
 | |
| 
 | |
| 
 | |
|     .tuning_steps =  {
 | |
|         {FT757GX_ALL_RX_MODES,10},
 | |
|         RIG_TS_END,
 | |
|     },
 | |
| 
 | |
|     /* mode/filter list, .remember =  order matters! */
 | |
|     .filters =  {
 | |
|         {RIG_MODE_SSB|RIG_MODE_CW,  kHz(2.7)},
 | |
|         {RIG_MODE_CW,  Hz(600)},    /* narrow */
 | |
|         {RIG_MODE_AM,  kHz(6)},
 | |
|         {RIG_MODE_FM,  kHz(15)},
 | |
| 
 | |
|         RIG_FLT_END,
 | |
|     },
 | |
| 
 | |
|     .str_cal =      FT757GXII_STR_CAL,
 | |
| 
 | |
|     .priv =         NULL,               /* private data */
 | |
| 
 | |
|     .rig_init =     ft757_init,
 | |
|     .rig_cleanup =  ft757_cleanup,
 | |
|     .rig_open =     ft757_open,         /* port opened */
 | |
|     .rig_close =    NULL,               /* port closed */
 | |
| 
 | |
|     .set_freq =     ft757_set_freq,     /* set freq */
 | |
|     .get_freq =     ft757_get_freq,     /* get freq */
 | |
|     .set_mode =     ft757_set_mode,     /* set mode */
 | |
|     .get_mode =     ft757_get_mode,     /* get mode */
 | |
|     .set_vfo =      ft757_set_vfo,      /* set vfo */
 | |
|     .get_vfo =      ft757_get_vfo,      /* get vfo */
 | |
|     .get_level =    ft757_get_level,
 | |
|     .get_ptt =      ft757_get_ptt,      /* get ptt */
 | |
| };
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * _init
 | |
|  *
 | |
|  */
 | |
| 
 | |
| int ft757_init(RIG *rig)
 | |
| {
 | |
|     struct ft757_priv_data *p;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     if (!rig)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     p = (struct ft757_priv_data * ) calloc(1, sizeof(struct ft757_priv_data));
 | |
|     if (!p)         /* whoops! memory shortage! */
 | |
|         return -RIG_ENOMEM;
 | |
|     p->curfreq = 1e6;
 | |
| 
 | |
|     /* TODO: read pacing from preferences */
 | |
| 
 | |
|     p->pacing = FT757GX_PACING_DEFAULT_VALUE;   /* set pacing to minimum for now */
 | |
|     p->read_update_delay = FT757GX_DEFAULT_READ_TIMEOUT; /* set update timeout to safe value */
 | |
|     p->current_vfo =  RIG_VFO_A;                /* default to VFO_A ? */
 | |
|     rig->state.priv = (void *)p;
 | |
| 
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * ft757_cleanup routine
 | |
|  * the serial port is closed by the frontend
 | |
|  */
 | |
| 
 | |
| int ft757_cleanup(RIG *rig)
 | |
| {
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     if (rig->state.priv)
 | |
|         free(rig->state.priv);
 | |
|     rig->state.priv = NULL;
 | |
| 
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * ft757_open  routine
 | |
|  *
 | |
|  */
 | |
| 
 | |
| int ft757_open(RIG *rig)
 | |
| {
 | |
|     struct ft757_priv_data *priv = (struct ft757_priv_data *)rig->state.priv;
 | |
|     int retval;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     /* FT757GX has a write-only serial port: don't try to read status data */
 | |
|     if (rig->caps->rig_model == RIG_MODEL_FT757) {
 | |
|       memset(priv->update_data, 0, FT757GX_STATUS_UPDATE_DATA_LENGTH);
 | |
|     } else {
 | |
|         /* read back the 75 status bytes from FT757GXII */
 | |
|         retval = ft757_get_update_data(rig);
 | |
|         if (retval < 0) {
 | |
|            memset(priv->update_data, 0, FT757GX_STATUS_UPDATE_DATA_LENGTH);
 | |
|            return retval;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * This command only functions when operating on a vfo.
 | |
|  * TODO: test Status Update Byte 1
 | |
|  *
 | |
|  */
 | |
| 
 | |
| int ft757_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
 | |
| {
 | |
|     struct ft757_priv_data *priv = (struct ft757_priv_data *)rig->state.priv;
 | |
|     unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0a};
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called. Freq=%"PRIfreq"\n", __func__, freq);
 | |
| 
 | |
|     if (!rig)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     /* fill in first four bytes */
 | |
|     to_bcd(cmd, freq/10, BCD_LEN);
 | |
| 
 | |
|     priv->curfreq = freq;
 | |
|     return write_block(&rig->state.rigport, (char *)cmd, YAESU_CMD_LENGTH);
 | |
| }
 | |
| 
 | |
| 
 | |
| int ft757_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
 | |
| {
 | |
|     unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0c};
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     if (!rig)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: mode = %d, width = %d\n",
 | |
|               __func__, mode, width);
 | |
| 
 | |
|     if (mode == RIG_MODE_NONE)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     /* fill in p1 */
 | |
|     cmd[3] = mode2rig(rig, mode, width);
 | |
| 
 | |
|     return write_block(&rig->state.rigport, (char *)cmd, YAESU_CMD_LENGTH);
 | |
| }
 | |
| 
 | |
| 
 | |
| int ft757gx_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
 | |
| {
 | |
|     struct ft757_priv_data *priv = (struct ft757_priv_data *)rig->state.priv;
 | |
|     if (priv->fakefreq) { // only return last freq set when fakeit is turned on
 | |
|        *freq = priv->curfreq;
 | |
|        return RIG_OK;
 | |
|     }
 | |
|     return RIG_ENAVAIL;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Return Freq
 | |
|  */
 | |
| 
 | |
| int ft757_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
 | |
| {
 | |
|     struct ft757_priv_data *priv = (struct ft757_priv_data *)rig->state.priv;
 | |
|     int retval;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     if (!rig)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     retval = ft757_get_update_data(rig);    /* get whole shebang from rig */
 | |
|     if (retval < 0)
 | |
|         return retval;
 | |
| 
 | |
|     /* grab freq (little endian format) and convert */
 | |
|     switch(vfo) {
 | |
|     case RIG_VFO_CURR:
 | |
|         *freq = 10 * from_bcd(priv->update_data+STATUS_CURR_FREQ, BCD_LEN);
 | |
|         break;
 | |
|     case RIG_VFO_A:
 | |
|         *freq = 10 * from_bcd(priv->update_data+STATUS_VFOA_FREQ, BCD_LEN);
 | |
|         break;
 | |
|     case RIG_VFO_B:
 | |
|         *freq = 10 * from_bcd(priv->update_data+STATUS_VFOB_FREQ, BCD_LEN);
 | |
|         break;
 | |
|     default:
 | |
|         return -RIG_EINVAL;     /* sorry, wrong VFO */
 | |
|     }
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE,"%s returning: Freq=%"PRIfreq"\n", __func__, *freq );
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| int ft757_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
 | |
| {
 | |
|     struct ft757_priv_data *priv = (struct ft757_priv_data *)rig->state.priv;
 | |
|     int retval;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     if (!rig)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     retval = ft757_get_update_data(rig);    /* get whole shebang from rig */
 | |
|     if (retval < 0)
 | |
|         return retval;
 | |
| 
 | |
|     switch(vfo) {
 | |
|     case RIG_VFO_CURR:
 | |
|         retval = rig2mode(rig, priv->update_data[STATUS_CURR_MODE], mode, width);
 | |
|         break;
 | |
|     case RIG_VFO_A:
 | |
|         retval = rig2mode(rig, priv->update_data[STATUS_VFOA_MODE], mode, width);
 | |
|         break;
 | |
|     case RIG_VFO_B:
 | |
|         retval = rig2mode(rig, priv->update_data[STATUS_VFOB_MODE], mode, width);
 | |
|         break;
 | |
|     default:
 | |
|         return -RIG_EINVAL;     /* sorry, wrong VFO */
 | |
|     }
 | |
| 
 | |
|     return retval;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * set vfo and store requested vfo for later RIG_VFO_CURR
 | |
|  * requests.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| int ft757_set_vfo(RIG *rig, vfo_t vfo)
 | |
| {
 | |
|     unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x05};
 | |
|     struct ft757_priv_data *priv = (struct ft757_priv_data *)rig->state.priv;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     if (!rig)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     switch(vfo) {
 | |
|     case RIG_VFO_CURR:
 | |
|         return RIG_OK;
 | |
|     case RIG_VFO_A:
 | |
|         cmd[3] = 0x00;          /* VFO A */
 | |
|         break;
 | |
|     case RIG_VFO_B:
 | |
|         cmd[3] = 0x01;          /* VFO B */
 | |
|         break;
 | |
|     default:
 | |
|         return -RIG_EINVAL;     /* sorry, wrong VFO */
 | |
|     }
 | |
| 
 | |
|     priv->current_vfo = vfo;
 | |
| 
 | |
|     return write_block(&rig->state.rigport, (char *)cmd, YAESU_CMD_LENGTH);
 | |
| }
 | |
| 
 | |
| 
 | |
| int ft757_get_vfo(RIG *rig, vfo_t *vfo)
 | |
| {
 | |
|     struct ft757_priv_data *priv = (struct ft757_priv_data *)rig->state.priv;
 | |
|     int retval;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     if (!rig)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     retval = ft757_get_update_data(rig);    /* get whole shebang from rig */
 | |
|     if (retval < 0)
 | |
|         return retval;
 | |
| 
 | |
|     if (priv->update_data[0] & 0x10)
 | |
|         return RIG_VFO_MEM;
 | |
|     else
 | |
|         if (priv->update_data[0] & 0x08)
 | |
|             return RIG_VFO_B;
 | |
|         else
 | |
|             return RIG_VFO_A;
 | |
| 
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| int ft757_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
 | |
| {
 | |
|     struct ft757_priv_data *priv = (struct ft757_priv_data *)rig->state.priv;
 | |
|     int retval;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     if (!rig)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     retval = ft757_get_update_data(rig);    /* get whole shebang from rig */
 | |
|     if (retval < 0)
 | |
|         return retval;
 | |
| 
 | |
|     *ptt = priv->update_data[0] & 0x20 ?  RIG_PTT_ON : RIG_PTT_OFF;
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| int ft757_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
 | |
| {
 | |
|     unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x01, 0x10};
 | |
|     int retval;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     if (!rig)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     if (level != RIG_LEVEL_RAWSTR)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     serial_flush(&rig->state.rigport);
 | |
| 
 | |
|     /* send READ STATUS(Meter only) cmd to rig  */
 | |
|     retval = write_block(&rig->state.rigport, (char *)cmd, YAESU_CMD_LENGTH);
 | |
|     if (retval < 0)
 | |
|         return retval;
 | |
| 
 | |
|     /* read back the 1 byte */
 | |
|     retval = read_block(&rig->state.rigport, (char *)cmd, 1);
 | |
| 
 | |
|     if (retval != 1) {
 | |
|         rig_debug(RIG_DEBUG_ERR,"%s: read meter failed %d.\n",
 | |
|                   __func__, retval);
 | |
| 
 | |
|         return retval < 0 ? retval : -RIG_EIO;
 | |
|     }
 | |
|     val->i = cmd[0];
 | |
| 
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * private helper function. Retrieves update data from rig.
 | |
|  * using pacing value and buffer indicated in *priv struct.
 | |
|  *
 | |
|  * need to use this when doing ft757_get_* stuff
 | |
|  */
 | |
| 
 | |
| int ft757_get_update_data(RIG *rig)
 | |
| {
 | |
|     unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x10};
 | |
|     struct ft757_priv_data *priv = (struct ft757_priv_data *)rig->state.priv;
 | |
|     int retval=0;
 | |
|     int nbtries ;
 | |
|     /* Maximum number of attempts to ask/read the data. */
 | |
|     int maxtries = rig->state.rigport.retry ;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called. Timeout=%ld ms, Retry=%d\n",
 | |
| 		    __func__, rig->state.rigport.timeout, maxtries);
 | |
| 
 | |
|     /* At least on one model, returns erraticaly a timeout. Increasing the timeout
 | |
|     does not fix things. So we restart the read from scratch, it works most of times. */
 | |
|     for( nbtries = 0 ; nbtries < maxtries ; nbtries++ )
 | |
|     {
 | |
|         serial_flush(&rig->state.rigport);
 | |
| 
 | |
|         /* send READ STATUS cmd to rig  */
 | |
|         retval = write_block(&rig->state.rigport, (char *)cmd, YAESU_CMD_LENGTH);
 | |
|         if (retval < 0)
 | |
|             return retval;
 | |
| 
 | |
|         /* read back the 75 status bytes */
 | |
|         retval = read_block(&rig->state.rigport,
 | |
|                             (char *)priv->update_data,
 | |
|                             FT757GX_STATUS_UPDATE_DATA_LENGTH);
 | |
|         if (retval == FT757GX_STATUS_UPDATE_DATA_LENGTH) {
 | |
|             break ;
 | |
| 	}
 | |
|         rig_debug(RIG_DEBUG_ERR,
 | |
|                   "%s: read update_data failed, %d octets of %d read, retry %d out of %d\n",
 | |
|                   __func__, retval, FT757GX_STATUS_UPDATE_DATA_LENGTH,
 | |
| 	          nbtries, maxtries);
 | |
| 	/* The delay is quadratic. */
 | |
| 	usleep(nbtries*nbtries*1000000);
 | |
|     }
 | |
| 
 | |
|     if (retval != FT757GX_STATUS_UPDATE_DATA_LENGTH) {
 | |
|         rig_debug(RIG_DEBUG_ERR,"%s: read update_data failed, %d octets of %d read.\n",
 | |
|                   __func__, retval, FT757GX_STATUS_UPDATE_DATA_LENGTH);
 | |
| 
 | |
|         return retval < 0 ? retval : -RIG_EIO;
 | |
|     }
 | |
| 
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| int mode2rig(RIG *rig, rmode_t mode, pbwidth_t width)
 | |
| {
 | |
|     int md;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     if (!rig)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     /*
 | |
|      * translate mode from generic to ft757 specific
 | |
|      */
 | |
|     switch(mode) {
 | |
|     case RIG_MODE_AM:
 | |
|         md = MODE_AM;
 | |
|         break;
 | |
|     case RIG_MODE_USB:
 | |
|         md = MODE_USB;
 | |
|         break;
 | |
|     case RIG_MODE_LSB:
 | |
|         md = MODE_LSB;
 | |
|         break;
 | |
|     case RIG_MODE_FM:
 | |
|         md = MODE_FM;
 | |
|         break;
 | |
|     case RIG_MODE_CW:
 | |
|         if (width == RIG_PASSBAND_NORMAL ||
 | |
|             width >= rig_passband_normal(rig, mode))
 | |
|             md = MODE_CWW;
 | |
|         else
 | |
|             md = MODE_CWN;
 | |
|         break;
 | |
|     default:
 | |
|         return -RIG_EINVAL;         /* sorry, wrong MODE */
 | |
|     }
 | |
| 
 | |
|     return md;
 | |
| }
 | |
| 
 | |
| 
 | |
| int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width)
 | |
| {
 | |
|     rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|     if (!rig)
 | |
|         return -RIG_EINVAL;
 | |
| 
 | |
|     /*
 | |
|      * translate mode from ft757 specific to generic
 | |
|      */
 | |
|     switch(md) {
 | |
|     case MODE_AM:
 | |
|         *mode = RIG_MODE_AM;
 | |
|         break;
 | |
|     case MODE_USB:
 | |
|         *mode = RIG_MODE_USB;
 | |
|         break;
 | |
|     case MODE_LSB:
 | |
|         *mode = RIG_MODE_LSB;
 | |
|         break;
 | |
|     case MODE_FM:
 | |
|         *mode = RIG_MODE_FM;
 | |
|         break;
 | |
|     case MODE_CWW:
 | |
|     case MODE_CWN:
 | |
|         *mode = RIG_MODE_CW;
 | |
|         break;
 | |
|     default:
 | |
|         return -RIG_EINVAL;         /* sorry, wrong MODE */
 | |
|     }
 | |
|     if (md == MODE_CWN)
 | |
|         *width = rig_passband_narrow(rig, *mode);
 | |
|     else
 | |
|         *width = rig_passband_normal(rig, *mode);
 | |
| 
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Assumes rig!=NULL, rig->state.priv!=NULL
 | |
|  */
 | |
| int ft757gx_get_conf(RIG *rig, token_t token, char *val)
 | |
| {
 | |
|         struct ft757_priv_data *priv;
 | |
|         struct rig_state *rs;
 | |
| 
 | |
| 
 | |
|         rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__);
 | |
| 
 | |
|         rs = &rig->state;
 | |
|         priv = (struct ft757_priv_data*)rs->priv;
 | |
| 
 | |
| 
 | |
|         switch(token) {
 | |
|         case TOK_FAKEFREQ:
 | |
| 		sprintf(val,"%d",priv->fakefreq);
 | |
|                 break;
 | |
|         default:
 | |
| 		val = NULL;
 | |
|                 return -RIG_EINVAL;
 | |
|         }
 | |
|         return RIG_OK;
 | |
| }
 | |
| /*
 | |
|  * Assumes rig!=NULL, rig->state.priv!=NULL
 | |
|  */
 | |
| int ft757gx_set_conf(RIG *rig, token_t token, const char *val)
 | |
| {
 | |
|         struct ft757_priv_data *priv;
 | |
|         struct rig_state *rs;
 | |
| 
 | |
| 
 | |
|         rig_debug(RIG_DEBUG_VERBOSE, "%s called. val=%s\n", __func__, val);
 | |
| 
 | |
|         rs = &rig->state;
 | |
|         priv = (struct ft757_priv_data*)rs->priv;
 | |
| 
 | |
|         switch(token) {
 | |
|         case TOK_FAKEFREQ:
 | |
| 		priv->fakefreq = 0; // should only be 0 or 1 -- default to 0
 | |
|                 if (val[0] != '0')
 | |
|                         priv->fakefreq = 1;
 | |
| 		rig_debug(RIG_DEBUG_VERBOSE, "fakefreq=%d\n", __func__, priv->fakefreq);
 | |
| 
 | |
|                 break;
 | |
|         default:
 | |
|                 return -RIG_EINVAL;
 | |
|         }
 | |
|         return RIG_OK;
 | |
| }
 |