kopia lustrzana https://github.com/Hamlib/Hamlib
				
				
				
			
		
			
				
	
	
		
			799 wiersze
		
	
	
		
			29 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			799 wiersze
		
	
	
		
			29 KiB
		
	
	
	
		
			C
		
	
	
| /*
 | |
|  *  Copyright (c) 2010-2011 by Mikhail Kshevetskiy (mikhail.kshevetskiy@gmail.com)
 | |
|  *
 | |
|  *  Code based on VX-1700 CAT manual:
 | |
|  *  http://www.vertexstandard.com/downloadFile.cfm?FileID=3397&FileCatID=135&FileName=VX-1700_CAT_MANUAL_10_14_2008.pdf&FileContentType=application%2Fpdf
 | |
|  *
 | |
|  *  WARNING: this manual have two errors
 | |
|  *    1) Status Update Command (10h), U=01 returns  0..199 for channels 1..200
 | |
|  *    2) Frequency Data (bytes 1--4 of 9-Byte VFO Data Assignment, Status Update
 | |
|  *       Command (10h), U=02 and U=03) uses bytes 1--3 for frequency, byte 4 is
 | |
|  *       not used and always zero. Thus bytes 0x15,0xBE,0x68,0x00 means
 | |
|  *       frequency = 10 * 0x15BE68 = 10 * 1425000 = 14.25 MHz
 | |
|  *
 | |
|  *	$Id: vx1700.c,v 1.0 2010-12-27
 | |
|  *
 | |
|  *   This library is free software; you can redistribute it and/or modify
 | |
|  *   it under the terms of the GNU Library General Public License as
 | |
|  *   published by the Free Software Foundation; either version 2 of
 | |
|  *   the License, or (at your option) any later version.
 | |
|  *
 | |
|  *   This program 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 Library General Public License for more details.
 | |
|  *
 | |
|  *   You should have received a copy of the GNU Library General Public
 | |
|  *   License along with this library; if not, write to the Free Software
 | |
|  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #include "config.h"
 | |
| #endif
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| #include <unistd.h>
 | |
| 
 | |
| #include "idx_builtin.h"
 | |
| #include "hamlib/rig.h"
 | |
| #include "bandplan.h"
 | |
| #include "serial.h"
 | |
| #include "misc.h"
 | |
| #include "yaesu.h"
 | |
| #include "vx1700.h"
 | |
| 
 | |
| 
 | |
| static const yaesu_cmd_set_t ncmd[] = {
 | |
|   { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* Recall Memory */
 | |
|   { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* VFO to MEM */
 | |
|   { 0, { 0x00, 0x00, 0x01, 0x00, 0x03 } }, /* Hide Memory Channel */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* Select VFO (A) */
 | |
|   { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* Set Op Freq */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* OP Mode Set LSB */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* OP Mode Set USB */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* OP Mode Set CW-W */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* OP Mode Set CW-N */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* OP Mode Set AM */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* OP Mode Set RTTY LSB-W */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* OP Mode Set RTTY USB-W */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x0d, 0x0c } }, /* OP Mode Set H3E */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x0e, 0x0c } }, /* OP Mode Set RTTY LSB-N */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x0f, 0x0c } }, /* OP Mode Set RTTY USB-N */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT (OFF) */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT (ON) */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Update Memory Ch Number */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Update Op Data */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Update VFO Data */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x00, 0x18 } }, /* Set TX power low */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x00, 0x28 } }, /* Set TX power mid */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x00, 0x48 } }, /* Set TX power hi  */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* Copy RX to TX */
 | |
|   { 0, { 0x00, 0x00, 0x00, 0x00, 0x8a } }, /* Set TX Freq only */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x00, 0x8e } }, /* Step Operating Frequency Up */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x01, 0x8e } }, /* Step Operating Frequency Down */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read Meter */
 | |
|   { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read Status Flags */
 | |
| };
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Private data
 | |
|  */
 | |
| struct vx1700_priv_data{
 | |
| 	unsigned char	ch;	/* memory channel */
 | |
| };
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * vx1700 rigs capabilities.
 | |
|  */
 | |
| #define VX1700_MEM_CAP {	\
 | |
| 		.freq    = 1,	\
 | |
| 		.tx_freq = 1,	\
 | |
| 		.mode    = 1,	\
 | |
| 		.width   = 1,	\
 | |
| }
 | |
| 
 | |
| const struct rig_caps vx1700_caps = {
 | |
|     .rig_model =  RIG_MODEL_VX1700,
 | |
|     .model_name =  "VX-1700",
 | |
|     .mfg_name =  "Vertex Standart",
 | |
|     .version =  "1.0",
 | |
|     .copyright =  "LGPL",
 | |
|     .status =   RIG_STATUS_ALPHA,
 | |
|     .rig_type =  RIG_TYPE_TRANSCEIVER,
 | |
|     .ptt_type =  RIG_PTT_RIG,
 | |
|     .dcd_type =  RIG_DCD_NONE,	/* we have DCD pin in DATA Jack, but get_dcd() is unavailable (yet?) */
 | |
|     .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 =  0,
 | |
|     .post_write_delay =  0,
 | |
|     .timeout =  600,
 | |
|     .retry =  3,
 | |
| 
 | |
|     .has_get_func =  (RIG_FUNC_LOCK|RIG_FUNC_TUNER),
 | |
|     .has_set_func =  RIG_FUNC_NONE,
 | |
|     .has_get_level =  RIG_LEVEL_NONE,
 | |
|     .has_set_level =  RIG_LEVEL_RFPOWER,
 | |
|     .has_get_parm =  RIG_PARM_NONE,
 | |
|     .has_set_parm =  RIG_PARM_NONE,
 | |
|     .level_gran =  {
 | |
| 	[LVL_RFPOWER] = { .min = { .i = 0 }, .max = { .i = 2 } },
 | |
|     },
 | |
|     .parm_gran =  {},
 | |
|     .preamp =   { RIG_DBLST_END },
 | |
|     .attenuator =   { RIG_DBLST_END },
 | |
|     .max_rit =  Hz(0),
 | |
|     .max_xit =  Hz(0),
 | |
|     .max_ifshift =  Hz(0),
 | |
|     .vfo_ops =  VX1700_VFO_OPS,
 | |
|     .targetable_vfo =  0,
 | |
|     .transceive =  RIG_TRN_OFF,
 | |
|     .bank_qty =   0,
 | |
|     .chan_desc_sz =  0,
 | |
| 
 | |
|     .chan_list =  { { VX1700_MIN_CHANNEL, VX1700_MAX_CHANNEL, RIG_MTYPE_MEM, VX1700_MEM_CAP }, RIG_CHAN_END },
 | |
| 
 | |
|     .rx_range_list1 =  {
 | |
| 	{ kHz(30),   MHz(30),  VX1700_MODES, -1,    -1,     VX1700_VFO_ALL, VX1700_ANTS },
 | |
| 	RIG_FRNG_END,
 | |
|     },
 | |
|     .tx_range_list1 =  {
 | |
| 	{ kHz(1600), MHz(4)-1, VX1700_MODES, W(31), W(125), VX1700_VFO_ALL, VX1700_ANTS },
 | |
| 	{ kHz(4000), MHz(30),  VX1700_MODES, W(25), W(100), VX1700_VFO_ALL, VX1700_ANTS },
 | |
| 	RIG_FRNG_END,
 | |
|     },
 | |
| 
 | |
|     .rx_range_list2 =  {
 | |
| 	{ kHz(30),   MHz(30),  VX1700_MODES, -1,    -1,     VX1700_VFO_ALL, VX1700_ANTS },
 | |
| 	RIG_FRNG_END,
 | |
|     },
 | |
|     .tx_range_list2 =  {
 | |
| 	{ kHz(1600), MHz(4)-1, VX1700_MODES, W(31), W(125), VX1700_VFO_ALL, VX1700_ANTS },
 | |
| 	{ kHz(4000), MHz(30),  VX1700_MODES, W(25), W(100), VX1700_VFO_ALL, VX1700_ANTS },
 | |
| 	RIG_FRNG_END,
 | |
|     },
 | |
| 
 | |
|     .tuning_steps =  {
 | |
| 	{ VX1700_MODES, 100 },
 | |
| 	RIG_TS_END,
 | |
|     },
 | |
| 
 | |
|     /* mode/filter list, remember: order matters! */
 | |
|     .filters =  {
 | |
| 	{ RIG_MODE_AM,                                  VX1700_FILTER_WIDTH_AM     },
 | |
| 	{ RIG_MODE_SSB,                                 VX1700_FILTER_WIDTH_SSB    },
 | |
| 	{ RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_RTTYR, VX1700_FILTER_WIDTH_WIDE   },
 | |
| 	{ RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_RTTYR, VX1700_FILTER_WIDTH_NARROW },
 | |
| 	RIG_FLT_END,
 | |
|     },
 | |
| 
 | |
|     .priv =  NULL,
 | |
| 
 | |
|     .rig_init       = vx1700_init,
 | |
|     .rig_open       = vx1700_open,
 | |
|     .rig_cleanup    = vx1700_cleanup,
 | |
| 
 | |
|     .set_vfo        = vx1700_set_vfo,
 | |
|     .get_vfo        = vx1700_get_vfo,
 | |
|     .set_freq       = vx1700_set_freq,
 | |
|     .get_freq       = vx1700_get_freq,
 | |
|     .set_split_freq = vx1700_set_split_freq,
 | |
|     .get_split_freq = vx1700_get_split_freq,
 | |
|     .set_mode       = vx1700_set_mode,
 | |
|     .get_mode       = vx1700_get_mode,
 | |
|     .get_ptt        = vx1700_get_ptt,
 | |
|     .set_ptt        = vx1700_set_ptt,
 | |
|     .get_info       = vx1700_get_info,
 | |
|     .set_func       = vx1700_set_func,
 | |
|     .get_func       = vx1700_get_func,
 | |
|     .set_level      = vx1700_set_level,
 | |
|     .get_level      = vx1700_get_level,
 | |
|     .set_mem        = vx1700_set_mem,
 | |
|     .get_mem        = vx1700_get_mem,
 | |
|     .vfo_op         = vx1700_vfo_op,
 | |
| };
 | |
| 
 | |
| 
 | |
| static inline freq_t vx1700_read_freq_from_buf(const unsigned char p[]){
 | |
|     /* WARNING: documentation bug, actually frequency stored in bytes 0..2 only,
 | |
|                 byte 3 is not used and contain zero */
 | |
|     return ((((((unsigned)p[0]) << 8) + p[1]) << 8) + p[2]) * 10.0;
 | |
| }
 | |
| 
 | |
| static inline int vx1700_channel_is_ok(unsigned char channel){
 | |
|     return ((channel >= VX1700_MIN_CHANNEL) &&
 | |
|             (channel <= VX1700_MAX_CHANNEL)) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Function definitions below
 | |
|  */
 | |
| static int vx1700_do_transaction(RIG *rig, const unsigned char cmd[YAESU_CMD_LENGTH],
 | |
|                                  unsigned char *retbuf, size_t retbuf_len){
 | |
|     struct rig_state	*rs;
 | |
|     unsigned char	default_retbuf[1];
 | |
|     int			retval;
 | |
| 
 | |
|     if (retbuf == NULL){
 | |
| 	retbuf = default_retbuf;
 | |
| 	retbuf_len = sizeof(default_retbuf);
 | |
|     }
 | |
|     rs = &rig->state;
 | |
|     memset(retbuf, 0, retbuf_len);
 | |
| 
 | |
|     serial_flush(&rs->rigport);
 | |
|     retval = write_block(&rs->rigport, (const char*)cmd, YAESU_CMD_LENGTH);
 | |
|     if (retval != RIG_OK) return retval;
 | |
| 
 | |
|     retval = read_block(&rs->rigport, (char*)retbuf, retbuf_len);
 | |
|     if (retval != retbuf_len){
 | |
| 	if ((retval == 1) && (retbuf[0] == VX1700_CMD_RETCODE_ERROR)) return -RIG_ERJCTED;
 | |
| 	return -RIG_EIO;
 | |
|     }
 | |
|     if (retval == 1){
 | |
| 	if ((cmd[4] == VX1700_CMD_UPDATE) && (cmd[3] == 0x01)){
 | |
| 	    /* read memory channel number */
 | |
| 	    if (vx1700_channel_is_ok(retbuf[0] + 1)){
 | |
| 		/* WARNING: Documentation bug, actually
 | |
| 		            we got 0--199 for channels 1--200 */
 | |
| 		return RIG_OK;
 | |
| 	    }
 | |
| 	    if (retbuf[0] == VX1700_CMD_RETCODE_ERROR) return -RIG_ERJCTED;
 | |
| 	    return -RIG_EIO;
 | |
| 	}
 | |
| 	if (retbuf[0] == VX1700_CMD_RETCODE_OK) return RIG_OK;
 | |
| 	if (retbuf[0] == VX1700_CMD_RETCODE_ERROR) return -RIG_ERJCTED;
 | |
| 	return -RIG_EIO;
 | |
|     }
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Private helper function to send a complete command sequence.
 | |
|  *
 | |
|  * TODO: place variant of this in yaesu.c
 | |
|  *
 | |
|  * Arguments:   *rig    Valid RIG instance
 | |
|  *              ci      Command index of the ncmd struct
 | |
|  *
 | |
|  * Returns:     RIG_OK if all called functions are successful,
 | |
|  *              otherwise returns error from called functiion
 | |
|  */
 | |
| static int vx1700_do_static_cmd(RIG *rig, unsigned char ci){
 | |
|     if (rig == NULL) return -RIG_EINVAL;
 | |
|     if ( ! ncmd[ci].ncomp){
 | |
| 	rig_debug(RIG_DEBUG_TRACE,
 | |
| 	          "%s: Attempt to send incomplete sequence\n", __func__);
 | |
| 	return -RIG_EINVAL;
 | |
|     }
 | |
|     return vx1700_do_transaction(rig, ncmd[ci].nseq, NULL, 0);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Private helper function to build and then send a complete command
 | |
|  * sequence.
 | |
|  *
 | |
|  * TODO: place variant of this in yaesu.c
 | |
|  *
 | |
|  * Arguments:   *rig    Valid RIG instance
 | |
|  *              ci      Command index of the ncmd struct
 | |
|  *              p1-p4   Command parameters
 | |
|  *
 | |
|  * Returns:     RIG_OK if all called functions are successful,
 | |
|  *              otherwise returns error from called functiion
 | |
|  */
 | |
| static int vx1700_do_dynamic_cmd(RIG *rig, unsigned char ci,
 | |
|                                  unsigned char p1, unsigned char p2,
 | |
|                                  unsigned char p3, unsigned char p4){
 | |
| 
 | |
|     unsigned char	cmd[YAESU_CMD_LENGTH];
 | |
| 
 | |
|     if (rig == NULL) return -RIG_EINVAL;
 | |
|     if (ncmd[ci].ncomp){
 | |
| 	rig_debug(RIG_DEBUG_TRACE,
 | |
| 	          "%s: Attempt to modify complete sequence\n", __func__);
 | |
| 	return -RIG_EINVAL;
 | |
|     }
 | |
| 
 | |
|     memcpy(&cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH);
 | |
|     cmd[3] = p1;
 | |
|     cmd[2] = p2;
 | |
|     cmd[1] = p3;
 | |
|     cmd[0] = p4;
 | |
|     return vx1700_do_transaction(rig, cmd, NULL, 0);
 | |
| }
 | |
| 
 | |
| static int vx1700_do_freq_cmd(RIG *rig, unsigned char ci, freq_t freq){
 | |
|     unsigned char	cmd[YAESU_CMD_LENGTH];
 | |
| 
 | |
|     if (rig == NULL) return -RIG_EINVAL;
 | |
|     if ((ci != VX1700_NATIVE_FREQ_SET) && (ci != VX1700_NATIVE_TX_FREQ_SET)){
 | |
| 	rig_debug(RIG_DEBUG_TRACE,
 | |
| 	          "%s: Attempt to use non freqency sequence\n", __func__);
 | |
| 	return -RIG_EINVAL;
 | |
|     }
 | |
|     memcpy(&cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH);
 | |
|     to_bcd(cmd, freq / 10, VX1700_BCD_DIAL);
 | |
|     return vx1700_do_transaction(rig, cmd, NULL, 0);
 | |
| }
 | |
| 
 | |
| static inline int vx1700_read_mem_channel_number(RIG *rig, unsigned char *channel){
 | |
|     int			ret;
 | |
|     unsigned char	reply[VX1700_MEM_CHNL_LENGTH];
 | |
| 
 | |
|     ret = vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_UPDATE_MEM_CHNL].nseq,
 | |
|                                 reply, VX1700_MEM_CHNL_LENGTH);
 | |
|     if (ret == -RIG_ERJCTED){
 | |
| 	/* we are on VFO mode, so memory channel is not available at the moment */
 | |
| 	*channel = VX1700_MIN_CHANNEL - 1;
 | |
| 	return RIG_OK;
 | |
|     }
 | |
|     if (ret != RIG_OK) return ret;
 | |
| 
 | |
|     /* WARNING: Documentation bug, actually we got 0--199 for channels 1--200 */
 | |
|     *channel = VX1700_MIN_CHANNEL + reply[0];
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| static inline int vx1700_read_status_flags(RIG *rig, unsigned char reply[]){
 | |
|     if (rig == NULL) return -RIG_EINVAL;
 | |
|     return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_READ_FLAGS].nseq,
 | |
|                                  reply, VX1700_STATUS_FLAGS_LENGTH);
 | |
| }
 | |
| 
 | |
| static inline int vx1700_read_meter(RIG *rig, unsigned char reply[]){
 | |
|     if (rig == NULL) return -RIG_EINVAL;
 | |
|     return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_READ_METER].nseq,
 | |
|                                  reply, VX1700_READ_METER_LENGTH);
 | |
| }
 | |
| 
 | |
| static inline int vx1700_read_vfo_data_raw(RIG *rig, unsigned char reply[]){
 | |
|     if (rig == NULL) return -RIG_EINVAL;
 | |
|     return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_UPDATE_VFO_DATA].nseq,
 | |
|                                  reply, VX1700_VFO_DATA_LENGTH);
 | |
| }
 | |
| 
 | |
| static inline int vx1700_read_op_data_raw(RIG *rig, unsigned char reply[]){
 | |
|     if (rig == NULL) return -RIG_EINVAL;
 | |
|     return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_UPDATE_OP_DATA].nseq,
 | |
|                                  reply, VX1700_OP_DATA_LENGTH);
 | |
| }
 | |
| 
 | |
| #if 0 /* unused; re-enabled as needed. */
 | |
| static int vx1700_read_vfo_data(RIG *rig, unsigned char *hwmode,
 | |
|                                 freq_t *rx_freq, freq_t *tx_freq){
 | |
|     int			ret;
 | |
|     unsigned char	reply[VX1700_VFO_DATA_LENGTH];
 | |
| 
 | |
|     if ((ret = vx1700_read_vfo_data_raw(rig, reply)) != RIG_OK) return ret;
 | |
|     if (hwmode  != NULL) *hwmode  = reply[6];
 | |
|     if (rx_freq != NULL) *rx_freq = vx1700_read_freq_from_buf(reply + 1);
 | |
|     if (tx_freq != NULL) *tx_freq = vx1700_read_freq_from_buf(reply + 10);
 | |
|     return RIG_OK;
 | |
| }
 | |
| #endif /* unused */
 | |
| 
 | |
| static int vx1700_read_op_data(RIG *rig, unsigned char *hwmode,
 | |
|                                freq_t *rx_freq, freq_t *tx_freq){
 | |
|     int			ret;
 | |
|     unsigned char	reply[VX1700_OP_DATA_LENGTH];
 | |
| 
 | |
|     if ((ret = vx1700_read_op_data_raw(rig, reply)) != RIG_OK) return ret;
 | |
|     if (hwmode  != NULL) *hwmode  = reply[7];
 | |
|     if (rx_freq != NULL) *rx_freq = vx1700_read_freq_from_buf(reply + 2);
 | |
|     if (tx_freq != NULL) *tx_freq = vx1700_read_freq_from_buf(reply + 11);
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| static const char* vx1700_get_hwmode_str(unsigned char hwmode){
 | |
|     switch(hwmode){
 | |
| 	case VX1700_MODE_AM:
 | |
| 	    return "AM (A3E)";
 | |
| 	case VX1700_MODE_LSB:
 | |
| 	    return "LSB (J3E)";
 | |
| 	case VX1700_MODE_USB:
 | |
| 	    return "USB (J3E)";
 | |
| 	case VX1700_MODE_CW_W:
 | |
| 	    return "CW (A1A-W)";
 | |
| 	case VX1700_MODE_CW_N:
 | |
| 	    return "CW (A1A-N)";
 | |
| 	case VX1700_MODE_RTTY:
 | |
| 	    return "RTTY[R] (J2B)";
 | |
| 	default:
 | |
| 	    return "unknown";
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void vx1700_parse_vfo_data(const char *func,
 | |
|                                   const unsigned char buf[VX1700_VFO_DATA_LENGTH]){
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: rx.band_data=0x%02d\n", func, buf[0]);
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: rx.freq=%f\n",          func, vx1700_read_freq_from_buf(buf + 1));
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: rx.mode=0x%02d, %s\n",  func, buf[6], vx1700_get_hwmode_str(buf[6]));
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: tx.band_data=0x%02d\n", func, buf[9]);
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: tx.freq=%f\n",          func, vx1700_read_freq_from_buf(buf + 10));
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: tx.mode=0x%02d, %s\n",  func, buf[15], vx1700_get_hwmode_str(buf[15]));
 | |
| }
 | |
| 
 | |
| static void vx1700_parse_op_data(const char *func,
 | |
|                                  const unsigned char buf[VX1700_OP_DATA_LENGTH]){
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: op-data: Semi Duplex Memory Channel: %s\n", func, (buf[0] & 0x20) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: op-data: Alpha Numeric Channel: %s\n",      func, (buf[0] & 0x40) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: op-data: Erased Memory Channel: %s\n",      func, (buf[0] & 0x80) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: op-data: rx.band_data=0x%02d\n",            func, buf[1]);
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: op-data: rx.freq=%f\n",                     func, vx1700_read_freq_from_buf(buf + 2));
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: op-data: rx.mode=0x%02d, %s\n",             func, buf[7], vx1700_get_hwmode_str(buf[7]));
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: op-data: tx.band_data=0x%02d\n",            func, buf[10]);
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: op-data: tx.freq=%f\n",                     func, vx1700_read_freq_from_buf(buf + 11));
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: op-data: tx.mode=0x%02d, %s\n",             func, buf[16], vx1700_get_hwmode_str(buf[16]));
 | |
| }
 | |
| 
 | |
| static void vx1700_parse_status_flags(const char *func,
 | |
|                                       const unsigned char buf[VX1700_STATUS_FLAGS_LENGTH]){
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: Lock: %s\n",               func, (buf[0] & VX1700_SF_LOCKED) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: Memory Mode: %s\n",        func, (buf[0] & VX1700_SF_MEM) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: VFO Mode: %s\n",           func, (buf[0] & VX1700_SF_VFO) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: PTT closed by CAT: %s\n",  func, (buf[1] & VX1700_SF_PTT_BY_CAT) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: Scanning paused: %s\n",    func, (buf[1] & VX1700_SF_MEM_SCAN_PAUSE) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: Scanning enabled: %s\n",   func, (buf[1] & VX1700_SF_MEM_SCAN) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: Narrow RTTY filter: %s\n", func, (buf[1] & VX1700_SF_RTTY_FILTER_NARROW) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: Narrow CW filter: %s\n",   func, (buf[1] & VX1700_SF_CW_FILTER_NARROW) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: USB for RTTY: %s\n",       func, (buf[1] & VX1700_SF_RTTY_USB) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: 10 Watt TX output: %s\n",  func, (buf[2] & VX1700_SF_10W_TX) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: Antenna Tuner: %s\n",      func, (buf[2] & VX1700_SF_TUNER_ON) ? "on" : "off");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: Transmission: %s\n",       func, (buf[2] & VX1700_SF_TRANSMISSION_ON) ? "yes" : "no");
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: flags: end bytes (0x06, 0x04): 0x%02x, 0x%02x\n", func, buf[3], buf[4]);
 | |
| }
 | |
| 
 | |
| static void vx1700_parse_meter(const char *func,
 | |
|                                const unsigned char buf[VX1700_READ_METER_LENGTH]){
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: meter: data: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", __func__, buf[0], buf[1], buf[2], buf[3]);
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: meter: end byte (0xF7): 0x%02x\n", __func__, buf[4]);
 | |
| }
 | |
| 
 | |
| static void dump_radio_state(RIG *rig){
 | |
|     unsigned char	channel = 0;
 | |
|     unsigned char	reply[VX1700_OP_DATA_LENGTH];
 | |
|     int			ret;
 | |
| 
 | |
|     if (rig == NULL) return;
 | |
| 
 | |
|     if ((ret = vx1700_read_mem_channel_number(rig, &channel)) != RIG_OK) return;
 | |
|     if (vx1700_channel_is_ok(channel))
 | |
| 	rig_debug(RIG_DEBUG_TRACE, "%s: Current Memory Channel %d\n", __func__, (int)channel);
 | |
|     else
 | |
| 	rig_debug(RIG_DEBUG_TRACE, "%s: Memory Channel number is not available at the moment\n", __func__);
 | |
| 
 | |
|     if ((ret = vx1700_read_op_data_raw(rig, reply)) != RIG_OK) return;
 | |
|     vx1700_parse_op_data(__func__, reply);
 | |
|     if ((ret = vx1700_read_vfo_data_raw(rig, reply)) != RIG_OK) return;
 | |
|     vx1700_parse_vfo_data(__func__, reply);
 | |
|     if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) return;
 | |
|     vx1700_parse_status_flags(__func__, reply);
 | |
|     if ((ret = vx1700_read_meter(rig, reply)) != RIG_OK) return;
 | |
|     vx1700_parse_meter(__func__, reply);
 | |
| }
 | |
| 
 | |
| static int vx1700_init(RIG *rig){
 | |
|     struct vx1700_priv_data	*priv;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__);
 | |
|     priv = malloc(sizeof(struct vx1700_priv_data));
 | |
|     if (priv == NULL) return -RIG_ENOMEM;
 | |
| 
 | |
|     memset(priv, 0, sizeof(struct vx1700_priv_data));
 | |
|     priv->ch = 1;
 | |
|     rig->state.priv = (rig_ptr_t)priv;
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| static int vx1700_open(RIG *rig){
 | |
|     struct vx1700_priv_data	*priv = (struct vx1700_priv_data *)rig->state.priv;
 | |
|     struct rig_state		*state = &rig->state;
 | |
|     int				ret;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__);
 | |
| 
 | |
|     if ((ret = vx1700_get_vfo(rig, &state->current_vfo)) != RIG_OK) return ret;
 | |
|     if ((ret = vx1700_get_mode(rig, RIG_VFO_CURR, &state->current_mode,
 | |
|                                &state->current_width)) != RIG_OK) return ret;
 | |
|     if ((ret = vx1700_read_op_data(rig, NULL, &state->current_freq, NULL)) != RIG_OK) return ret;
 | |
|     if ((ret = vx1700_read_mem_channel_number(rig, &priv->ch)) != RIG_OK) return ret;
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| static int vx1700_cleanup(RIG *rig){
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__);
 | |
|     if (rig->state.priv != NULL) free(rig->state.priv);
 | |
|     rig->state.priv = NULL;
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| static const char * vx1700_get_info(RIG *rig){
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__);
 | |
|     dump_radio_state(rig);
 | |
|     return "NO_INFO";
 | |
| }
 | |
| 
 | |
| static int vx1700_set_vfo(RIG *rig, vfo_t vfo){
 | |
|     struct vx1700_priv_data	*priv = (struct vx1700_priv_data *)rig->state.priv;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s, vfo=%d\n", __func__, vfo);
 | |
|     switch(vfo){
 | |
| 	case RIG_VFO_CURR:
 | |
| 	    return RIG_OK;
 | |
| 	case RIG_VFO_VFO:
 | |
| 	case RIG_VFO_A:
 | |
| 	    return vx1700_do_static_cmd(rig, VX1700_NATIVE_VFO_A);
 | |
| 	case RIG_VFO_MEM:
 | |
| 	    return vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_RECALL_MEM, priv->ch, 0, 0, 0);
 | |
| 	default:
 | |
| 	    return -RIG_EINVAL;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int vx1700_get_vfo(RIG *rig, vfo_t *vfo){
 | |
|     int			ret;
 | |
|     unsigned char	reply[VX1700_STATUS_FLAGS_LENGTH];
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__);
 | |
|     if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) return ret;
 | |
|     *vfo = (reply[0] & VX1700_SF_MEM) ? RIG_VFO_MEM : RIG_VFO_A;
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| static int vx1700_set_freq(RIG *rig, vfo_t vfo, freq_t freq){
 | |
|     (void) vfo;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: freq=%f\n", __func__, freq);
 | |
|     return vx1700_do_freq_cmd(rig, VX1700_NATIVE_FREQ_SET, freq);
 | |
| }
 | |
| 
 | |
| static int vx1700_get_freq(RIG *rig, vfo_t vfo, freq_t *freq){
 | |
|     (void) vfo;
 | |
|     return vx1700_read_op_data(rig, NULL, freq, NULL);
 | |
| }
 | |
| 
 | |
| static int vx1700_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq){
 | |
|     (void) vfo;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: freq=%f\n", __func__, tx_freq);
 | |
|     return vx1700_do_freq_cmd(rig, VX1700_NATIVE_TX_FREQ_SET, tx_freq);
 | |
| }
 | |
| 
 | |
| static int vx1700_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq){
 | |
|     (void) vfo;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__);
 | |
|     return vx1700_read_op_data(rig, NULL, NULL, tx_freq);
 | |
| }
 | |
| 
 | |
| static int vx1700_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width){
 | |
|     (void) rig;
 | |
|     (void) vfo;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: mode=0x%04x, width=%d\n", __func__, (int) mode, (int) width);
 | |
| 
 | |
|     if (width == RIG_PASSBAND_NORMAL)
 | |
| 	width = rig_passband_normal(rig, mode);
 | |
| 
 | |
|     switch(mode){
 | |
| 	case RIG_MODE_AM:
 | |
| 	    return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_AM);
 | |
| 	case RIG_MODE_LSB:
 | |
| 	    return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_LSB);
 | |
| 	case RIG_MODE_USB:
 | |
| 	    return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_USB);
 | |
| 	case RIG_MODE_CW:
 | |
| 	    if (width > (VX1700_FILTER_WIDTH_NARROW + VX1700_FILTER_WIDTH_WIDE) / 2)
 | |
| 		return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_CW_W);
 | |
| 	    else
 | |
| 		return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_CW_N);
 | |
| 	case RIG_MODE_RTTY:
 | |
| 	    if (width > (VX1700_FILTER_WIDTH_NARROW + VX1700_FILTER_WIDTH_WIDE) / 2)
 | |
| 		return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_LSB_W);
 | |
| 	    else
 | |
| 		return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_LSB_N);
 | |
| 	case RIG_MODE_RTTYR:
 | |
| 	    if (width > (VX1700_FILTER_WIDTH_NARROW + VX1700_FILTER_WIDTH_WIDE) / 2)
 | |
| 		return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_USB_W);
 | |
| 	    else
 | |
| 		return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_USB_N);
 | |
| 	default:
 | |
| 	    return -RIG_EINVAL;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int vx1700_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width){
 | |
|     int			ret;
 | |
|     unsigned char	hwmode;
 | |
|     unsigned char	reply[VX1700_STATUS_FLAGS_LENGTH];
 | |
| 
 | |
|     (void) rig;
 | |
|     (void) vfo;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__);
 | |
| 
 | |
|     if ((ret = vx1700_read_op_data(rig, &hwmode, NULL, NULL)) != RIG_OK) return ret;
 | |
|     switch(hwmode){
 | |
| 	case VX1700_MODE_AM:
 | |
| 	    *mode  = RIG_MODE_AM;
 | |
| 	    *width = VX1700_FILTER_WIDTH_AM;
 | |
| 	    return RIG_OK;
 | |
| 
 | |
| 	case VX1700_MODE_LSB:
 | |
| 	    *mode  = RIG_MODE_LSB;
 | |
| 	    *width = VX1700_FILTER_WIDTH_SSB;
 | |
| 	    return RIG_OK;
 | |
| 
 | |
| 	case VX1700_MODE_USB:
 | |
| 	    *mode  = RIG_MODE_USB;
 | |
| 	    *width = VX1700_FILTER_WIDTH_SSB;
 | |
| 	    return RIG_OK;
 | |
| 
 | |
| 	case VX1700_MODE_CW_W:
 | |
| 	    *mode  = RIG_MODE_CW;
 | |
| 	    *width = VX1700_FILTER_WIDTH_WIDE;
 | |
| 	    return RIG_OK;
 | |
| 
 | |
| 	case VX1700_MODE_CW_N:
 | |
| 	    *mode  = RIG_MODE_CW;
 | |
| 	    *width = VX1700_FILTER_WIDTH_NARROW;
 | |
| 	    return RIG_OK;
 | |
| 
 | |
| 	case VX1700_MODE_RTTY:
 | |
| 	    if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) return ret;
 | |
| 	    *mode  = (reply[1] & VX1700_SF_RTTY_USB) ?
 | |
| 	             RIG_MODE_RTTYR : RIG_MODE_RTTY;
 | |
| 	    *width = (reply[1] & VX1700_SF_RTTY_FILTER_NARROW) ?
 | |
| 	             VX1700_FILTER_WIDTH_NARROW : VX1700_FILTER_WIDTH_WIDE;
 | |
| 	    return RIG_OK;
 | |
| 
 | |
| 	default:
 | |
| 	    return -RIG_EPROTO;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int vx1700_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt){
 | |
|     (void) rig;
 | |
|     (void) vfo;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s, ptt=%d\n", __func__, ptt);
 | |
|     return vx1700_do_static_cmd(rig, (ptt == RIG_PTT_OFF) ?
 | |
|                                 VX1700_NATIVE_PTT_OFF : VX1700_NATIVE_PTT_ON);
 | |
| }
 | |
| 
 | |
| static int vx1700_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt){
 | |
|     int			ret;
 | |
|     unsigned char	reply[VX1700_STATUS_FLAGS_LENGTH];
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__);
 | |
|     if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) return ret;
 | |
|     *ptt = (reply[1] & VX1700_SF_PTT_BY_CAT) ? RIG_PTT_ON : RIG_PTT_OFF;
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| static int vx1700_set_func(RIG *rig, vfo_t vfo, setting_t func, int status){
 | |
|     (void) rig;
 | |
|     (void) vfo;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: func=0x%04x, status=%d\n", __func__, func, status);
 | |
|     return -RIG_EINVAL;
 | |
| }
 | |
| 
 | |
| static int vx1700_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status){
 | |
|     int			ret;
 | |
|     unsigned char	reply[VX1700_STATUS_FLAGS_LENGTH];
 | |
| 
 | |
|     (void) rig;
 | |
|     (void) vfo;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: func=0x%04x\n", __func__, func);
 | |
| 
 | |
|     switch(func){
 | |
| 	case RIG_FUNC_LOCK:
 | |
| 	    if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) return ret;
 | |
| 	    *status = (reply[0] & VX1700_SF_LOCKED) ? 1 : 0;
 | |
| 	    return RIG_OK;
 | |
| 
 | |
| 	case RIG_FUNC_TUNER:
 | |
| 	    if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) return ret;
 | |
| 	    *status = (reply[2] & VX1700_SF_TUNER_ON) ? 1 : 0;
 | |
| 	    return RIG_OK;
 | |
| 
 | |
| 	default:
 | |
| 	    return -RIG_EINVAL;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int vx1700_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val){
 | |
|     (void) rig;
 | |
|     (void) vfo;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: level=0x%04x, val=???\n", __func__, level);
 | |
| 
 | |
|     switch(level){
 | |
| 	case RIG_LEVEL_RFPOWER:
 | |
| 	    if ((val.f < 0.0) || (val.f > 1.0)) return -RIG_EINVAL;
 | |
| 	    if (val.f < (1.0 / 3.0))
 | |
| 		return vx1700_do_static_cmd(rig, VX1700_NATIVE_TX_POWER_LOW);
 | |
| 	    if (val.f < (2.0 / 3.0))
 | |
| 		return vx1700_do_static_cmd(rig, VX1700_NATIVE_TX_POWER_MID);
 | |
| 	    return vx1700_do_static_cmd(rig, VX1700_NATIVE_TX_POWER_HI);
 | |
| 	default:
 | |
| 	    return -RIG_EINVAL;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int vx1700_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val){
 | |
|     (void) rig;
 | |
|     (void) vfo;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: level=0x%04x\n", __func__, level);
 | |
|     return -RIG_EINVAL;
 | |
| }
 | |
| 
 | |
| static int vx1700_set_mem(RIG *rig, vfo_t vfo, int ch){
 | |
|     struct vx1700_priv_data	*priv = (struct vx1700_priv_data *)rig->state.priv;
 | |
|     struct rig_state		*state = &rig->state;
 | |
|     int				ret;
 | |
| 
 | |
|     if ( ! vx1700_channel_is_ok(ch)) return -RIG_EINVAL;
 | |
|     if (vfo == RIG_VFO_CURR) vfo = state->current_vfo;
 | |
|     if (vfo == RIG_VFO_MEM){
 | |
| 	ret = vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_RECALL_MEM, ch, 0, 0, 0);
 | |
| 	if (ret == RIG_OK) priv->ch = ch;
 | |
| 	return ret;
 | |
|     }
 | |
| 
 | |
|     priv->ch = ch;
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| static int vx1700_get_mem(RIG *rig, vfo_t vfo, int *ch){
 | |
|     struct vx1700_priv_data	*priv = (struct vx1700_priv_data *)rig->state.priv;
 | |
|     struct rig_state		*state = &rig->state;
 | |
|     unsigned char		channel = 0;
 | |
|     int				ret;
 | |
| 
 | |
|     if (vfo == RIG_VFO_CURR) vfo = state->current_vfo;
 | |
|     if (vfo == RIG_VFO_MEM){
 | |
| 	ret = vx1700_read_mem_channel_number(rig, &channel);
 | |
| 	if (ret != RIG_OK) return ret;
 | |
| 	if (vx1700_channel_is_ok(channel)){
 | |
| 	    *ch = priv->ch = channel;
 | |
| 	    return RIG_OK;
 | |
| 	}
 | |
| 	return -RIG_ERJCTED;
 | |
|     }
 | |
| 
 | |
|     if ( ! vx1700_channel_is_ok(priv->ch)) return -RIG_ERJCTED;
 | |
|     *ch = priv->ch;
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| static int vx1700_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op){
 | |
|     struct vx1700_priv_data	*priv = (struct vx1700_priv_data *)rig->state.priv;
 | |
| 
 | |
|     (void) rig;
 | |
|     (void) vfo;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: op=0x%04x\n", __func__, (int) op);
 | |
| 
 | |
|     switch(op){
 | |
| 	case RIG_OP_TO_VFO:
 | |
| 	    return vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_RECALL_MEM, priv->ch, 0, 0, 0);
 | |
| 
 | |
| 	case RIG_OP_FROM_VFO:
 | |
| 	    return vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_VFO_TO_MEM, priv->ch, 0, 0, 0);
 | |
| 
 | |
| 	case RIG_OP_UP:
 | |
| 	    return vx1700_do_static_cmd(rig, VX1700_NATIVE_OP_FREQ_STEP_UP);
 | |
| 
 | |
| 	case RIG_OP_DOWN:
 | |
| 	    return vx1700_do_static_cmd(rig, VX1700_NATIVE_OP_FREQ_STEP_DOWN);
 | |
| 
 | |
| 	default:
 | |
| 	    return -RIG_EINVAL;
 | |
|     }
 | |
| }
 |