diff --git a/tentec/omnivii.c b/tentec/omnivii.c index 1069c9ffd..50d62423c 100644 --- a/tentec/omnivii.c +++ b/tentec/omnivii.c @@ -1,6 +1,7 @@ /* * Hamlib TenTenc backend - TT-588 description * Copyright (c) 2003-2009 by Stephane Fillod + * Modifications 2014 by Michael Black W9MDB for 1.036 firmware * * * This library is free software; you can redistribute it and/or @@ -27,9 +28,10 @@ #include #include +#include #include -#include "tentec2.h" #include "tentec.h" +#include "tentec2.h" #include "bandplan.h" struct tt588_priv_data { @@ -38,20 +40,31 @@ struct tt588_priv_data { }; -#define TT588_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM) +#define TT588_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_AM) #define TT588_RXMODES (TT588_MODES) #define TT588_FUNCS (RIG_FUNC_NR|RIG_FUNC_ANF) -#define TT588_LEVELS (RIG_LEVEL_STRENGTH|/*RIG_LEVEL_NB|*/ \ - RIG_LEVEL_SQL|/*RIG_LEVEL_IF|*/ \ - RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD| \ - RIG_LEVEL_RF|RIG_LEVEL_NR| \ - /*RIG_LEVEL_ANF|*/RIG_LEVEL_MICGAIN| \ - RIG_LEVEL_AF|RIG_LEVEL_AGC| \ - RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOX| \ - RIG_LEVEL_COMP|/*RIG_LEVEL_PREAMP|*/ \ - RIG_LEVEL_SWR|RIG_LEVEL_ATT) +#define TT588_LEVELS ( RIG_LEVEL_STRENGTH| \ + RIG_LEVEL_SQL| \ + RIG_LEVEL_SWR| \ + RIG_LEVEL_RF| \ + RIG_LEVEL_AF| \ + RIG_LEVEL_AGC| \ + RIG_LEVEL_PREAMP| \ + RIG_LEVEL_SWR| \ + RIG_LEVEL_ATT \ + /*RIG_LEVEL_NB| */ \ + /*RIG_LEVEL_IF| */ \ + /*RIG_LEVEL_RFPOWER| */ \ + /*RIG_LEVEL_KEYSPD| */ \ + /*RIG_LEVEL_ANF| */ \ + /*RIG_LEVEL_MICGAIN|*/ \ + /*RIG_LEVEL_NR| */ \ + /*RIG_LEVEL_VOXGAIN| */ \ + /*RIG_LEVEL_VOX| */\ + /*RIG_LEVEL_COMP|*/ \ + ) #define TT588_ANTS (RIG_ANT_1|RIG_ANT_2) @@ -66,12 +79,19 @@ struct tt588_priv_data { #define TT588_LSB '2' #define TT588_CW '3' #define TT588_FM '4' +#define TT588_CWR '5' +// What would FSK mode match in hamlib? Not implemented. +// #define TT588_FSK '6' #define EOM "\015" /* CR */ +#define FALSE 0 +#define TRUE (!FALSE) static int tt588_init(RIG *rig); static int tt588_reset(RIG *rig, reset_t reset); static int tt588_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tt588_set_freq(RIG *rig, vfo_t vfo, freq_t freq); +static int tt588_set_split_freq(RIG * rig, vfo_t vfo, freq_t tx_freq); +static int tt588_get_split_freq(RIG * rig, vfo_t vfo, freq_t *tx_freq); static int tt588_set_vfo(RIG *rig, vfo_t vfo); static int tt588_get_vfo(RIG *rig, vfo_t *vfo); static int tt588_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); @@ -79,23 +99,32 @@ static int tt588_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static char which_vfo(const RIG *rig, vfo_t vfo); static int tt588_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int tt588_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); - +static int tt588_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); +static int tt588_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); +static int tt588_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); +static int tt588_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); +static int tt588_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); +static int tt588_reset(RIG *rig, reset_t reset); +static const char *tt588_get_info(RIG *rig); +static int tt588_get_xit(RIG * rig, vfo_t vfo, shortfreq_t *xit); +static int tt588_set_xit(RIG * rig, vfo_t vfo, shortfreq_t xit); +static int tt588_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit); +#if 0 // these are example prototypes for remote operation +static int tt588_get_ant(RIG * rig, vfo_t vfo, ant_t *ant); +static int tt588_set_ant(RIG * rig, vfo_t vfo, ant_t ant); +#endif /* * tt588 transceiver capabilities. * - * Protocol is documented at - * http://www.rfsquared.com/ - * - * Only set_freq is supposed to work. - * This is a skelton, cloned after TT-538 Jupiter. + * Protocol is documented at the tentec site */ const struct rig_caps tt588_caps = { .rig_model = RIG_MODEL_TT588, .model_name = "TT-588 Omni VII", .mfg_name = "Ten-Tec", -.version = "0.3", +.version = "0.4", .copyright = "LGPL", -.status = RIG_STATUS_ALPHA, +.status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, @@ -169,10 +198,10 @@ const struct rig_caps tt588_caps = { }, /* mode/filter list, remember: order matters! */ .filters = { - {RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM, kHz(2.4)}, - {RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM, 300}, - {RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM, kHz(8)}, - {RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM, 0}, /* 34 filters */ + {RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_AM, kHz(2.4)}, + {RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_AM, 300}, + {RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_AM, kHz(8)}, + {RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_AM, 0}, /* 34 filters */ {RIG_MODE_FM, kHz(15)}, /* TBC */ RIG_FLT_END, }, @@ -187,12 +216,23 @@ const struct rig_caps tt588_caps = { .get_mode = tt588_get_mode, .get_level = tt588_get_level, .set_level = tt588_set_level, -.set_split_vfo = tentec2_set_split_vfo, -.get_split_vfo = tentec2_get_split_vfo, -.set_ptt = tentec2_set_ptt, +.set_split_freq = tt588_set_split_freq, +.get_split_freq = tt588_get_split_freq, +.set_split_mode = tt588_set_split_mode, +.get_split_mode = tt588_get_split_mode, +.set_split_vfo = tt588_set_split_vfo, +.get_split_vfo = tt588_get_split_vfo, +.set_ptt = tt588_set_ptt, .reset = tt588_reset, -.get_info = tentec2_get_info, - +.get_info = tt588_get_info, +.get_xit = tt588_get_xit, +.set_xit = tt588_set_xit, +.get_rit = tt588_get_xit, +.set_rit = tt588_set_rit, +.attenuator = { 6, 12, 18, RIG_DBLST_END }, +// Antenna functions only in remote mode -- prototypes provided +//.get_ant = tt588_get_ant, +//.set_ant = tt588_set_ant }; /* Filter table for 588 reciver support. */ @@ -209,29 +249,46 @@ static int tt588_rxFilter[] = { /* I frequently see the Omni VII and my laptop get out of sync. A response from the 538 isn't seen by the laptop. A few "XX"s sometimes get things going again, hence this hack, er, function. */ - -static int tt588_transaction (RIG *rig, const char *cmd, int cmd_len, - char *data, int *data_len) +/* Note: data should be at least data_len+1 long for null byte insertion */ +static int tt588_transaction (RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { - char reset_buf[32]; - int i, reset_len, retval; + int i, retval; + struct rig_state *rs = &rig->state; - retval = tentec_transaction (rig, cmd, cmd_len, data, data_len); - if (retval == RIG_OK) - return retval; + // The original file had "A few XX's" due to sync problems + // So I put this in a try loop which should, hopefully, never be seen + for(i=0; i<3; ++i) { // We'll try 3 times + char xxbuf[32]; + serial_flush(&rs->rigport); - /* Try a few times to do a DSP reset to resync things. */ - for (i = 0; i < 3; i++) { - reset_len = 32; - retval = tentec_transaction (rig, "XX" EOM, 3, reset_buf, &reset_len); + // We add 1 to data_len here for the null byte inserted by read_string eventually + // That way all the callers can use the expected response length for the cmd_len paramter here + // Callers all need to ensure they have enough room in data for this + retval = write_block(&rs->rigport, cmd, cmd_len); + if (retval == RIG_OK) { + // All responses except from "XX" terminate with EOM (i.e. \r) so that is our stop char + char *term=EOM; + if (cmd[0]=='X') // we'll let the timeout take care of this as it shouldn't happen anyways + term = ""; + if(data) { + retval = read_string(&rs->rigport, data, (*data_len)+1, term, strlen(term)); + if (retval != -RIG_ETIMEOUT) + return RIG_OK; + rig_debug(RIG_DEBUG_ERR,"%s: read_string failed, try#%d\n", __FUNCTION__, i+1); + } + else { + return RIG_OK; // no data wanted so just return + } + } + else { + rig_debug(RIG_DEBUG_ERR,"%s: write_block failed, try#%d\n", __FUNCTION__, i+1); + } + write_block(&rs->rigport, "XX" EOM, 3); // we wont' worry about the response here + retval = read_string(&rs->rigport, xxbuf, sizeof(xxbuf), "", 0); // this should timeout if (retval != RIG_OK) - continue; /* Try again. This 1 didn't work. */ - if (strstr(reset_buf, "RADIO START")) - break; /* DSP reset successful! */ + rig_debug(RIG_DEBUG_ERR,"%s: XX command failed, try#%d\n", __FUNCTION__, i+1); } - - /* Try real command one last time... */ - return tentec_transaction (rig, cmd, cmd_len, data, data_len); + return retval; } /* @@ -242,6 +299,7 @@ int tt588_init(RIG *rig) { struct tt588_priv_data *priv; + rig_debug(RIG_DEBUG_VERBOSE, "%s:\n", __FUNCTION__); priv = (struct tt588_priv_data *) malloc(sizeof(struct tt588_priv_data)); if (!priv) { /* whoops! memory shortage! */ @@ -260,28 +318,40 @@ int tt588_init(RIG *rig) return RIG_OK; } +static int check_vfo(vfo_t vfo) +{ + switch(vfo) { // Omni VII only has A & B + case RIG_VFO_A:break; + case RIG_VFO_B:break; + case RIG_VFO_CURR:break; // will default to A in which_vfo + default: return FALSE; + } + return TRUE; +} + +// which_vfo returns the only two answers that work for commands +// Each calling routine should call check_vfo() before calling this +// Anything other than RIG_VFO_B will return 'A' since Omni VII only uses B on split +// So 'A' is always the default VFO static char which_vfo(const RIG *rig, vfo_t vfo) { - struct tt588_priv_data *priv = (struct tt588_priv_data *)rig->state.priv; - - if (vfo == RIG_VFO_CURR) - vfo = priv->vfo_curr; - - switch (vfo) { - case RIG_VFO_A: return 'A'; - case RIG_VFO_B: return 'B'; - case RIG_VFO_NONE: return 'N'; - default: - rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", - __FUNCTION__, rig_strvfo(vfo)); - return -RIG_EINVAL; - } + return RIG_VFO_B == vfo ? 'B' : 'A'; } int tt588_get_vfo(RIG *rig, vfo_t *vfo) { + static int getinfo = TRUE; + if (getinfo) { // this is the first call to this package so we do this here + getinfo = FALSE; + tt588_get_info(rig); + } struct tt588_priv_data *priv = (struct tt588_priv_data *) rig->state.priv; *vfo = priv->vfo_curr; + if(check_vfo(*vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(*vfo)); + return -RIG_EINVAL; + } + rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __FUNCTION__, rig_strvfo(*vfo)); return RIG_OK; } @@ -293,6 +363,12 @@ int tt588_set_vfo(RIG *rig, vfo_t vfo) { struct tt588_priv_data *priv = (struct tt588_priv_data *)rig->state.priv; + rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __FUNCTION__, rig_strvfo(vfo)); + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + if (vfo == RIG_VFO_CURR) return RIG_OK; @@ -307,14 +383,14 @@ int tt588_reset(RIG *rig, reset_t reset) { int retval, reset_len; char reset_buf[32]; + rig_debug(RIG_DEBUG_VERBOSE, "%s: reset=%d\n", __FUNCTION__, reset); reset_len = 32; retval = tt588_transaction (rig, "XX" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) return retval; if (!strstr(reset_buf, "RADIO START")) { - rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", - __FUNCTION__, reset_buf); + rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __FUNCTION__, reset_buf); return -RIG_EPROTO; } @@ -327,49 +403,58 @@ int tt588_reset(RIG *rig, reset_t reset) { */ int tt588_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { - char curVfo; int cmd_len, resp_len, retval; unsigned char cmdbuf[16], respbuf[32]; - cmd_len = sprintf((char *) cmdbuf, "?%c" EOM, which_vfo(rig, vfo)); - resp_len = 32; - retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) respbuf, &resp_len); + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + cmd_len = sprintf((char *) cmdbuf, "?%c" EOM,which_vfo(rig,vfo)); + resp_len = 6; + retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) respbuf, &resp_len); if (retval != RIG_OK) return retval; - curVfo = which_vfo(rig, vfo); - if (respbuf[0] != curVfo) { - rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", - __FUNCTION__, respbuf); - return -RIG_EPROTO; - } if (resp_len != 6) { - rig_debug(RIG_DEBUG_ERR, "%s: unexpected length '%d'\n", - __FUNCTION__, resp_len); + rig_debug(RIG_DEBUG_ERR, "%s: unexpected length '%d'\n", __FUNCTION__, resp_len); return -RIG_EPROTO; } - - *freq = (respbuf[1] << 24) - + (respbuf[2] << 16) - + (respbuf[3] << 8) - + respbuf[4]; - + if ((respbuf[0]=='A' || respbuf[0]=='B') && respbuf[5]==0x0d) { + *freq = (respbuf[1] << 24) + + (respbuf[2] << 16) + + (respbuf[3] << 8) + + respbuf[4]; + } + else { + *freq = 0; + } + rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%g\n", __FUNCTION__, rig_strvfo(vfo),*freq); return RIG_OK; } /* * tt588_set_freq * assumes rig!=NULL, rig->state.priv!=NULL - * assumes priv->mode in AM,CW,LSB or USB. */ - int tt588_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char bytes[4]; - int cmd_len; + int cmd_len, retval; unsigned char cmdbuf[16]; + rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%g\n", __FUNCTION__, rig_strvfo(vfo), freq); + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + + if (vfo == RIG_VFO_CURR) { + if ((retval = tt588_get_vfo(rig, &vfo)) != RIG_OK) + return retval; + rig_debug(RIG_DEBUG_VERBOSE, "%s: set_freq2 vfo=%s\n", __FUNCTION__, rig_strvfo(vfo)); + } /* Freq is 4 bytes long, MSB sent first. */ bytes[3] = ((int) freq >> 24) & 0xff; bytes[2] = ((int) freq >> 16) & 0xff; @@ -377,12 +462,51 @@ int tt588_set_freq(RIG *rig, vfo_t vfo, freq_t freq) bytes[0] = (int) freq & 0xff; cmd_len = sprintf((char *) cmdbuf, "*%c%c%c%c%c" EOM, - which_vfo(rig, vfo), - bytes[3], bytes[2], bytes[1], bytes[0]); + which_vfo(rig, vfo), + bytes[3], bytes[2], bytes[1], bytes[0]); return tt588_transaction(rig, (char *) cmdbuf, cmd_len, NULL, NULL); } +/* + * tt588_set_split_freq + */ +int tt588_set_split_freq(RIG * rig, vfo_t vfo, freq_t tx_freq) +{ + // VFOB is the split VFO + return tt588_set_freq(rig,RIG_VFO_B,tx_freq); +} + +/* + * tt588_get_split_freq + * assumes rig!=NULL, tx_freq!=NULL + */ +int tt588_get_split_freq(RIG * rig, vfo_t vfo, freq_t * tx_freq) +{ + // VFOB is the split VFO + return tt588_get_freq(rig,RIG_VFO_B,tx_freq); +} + +/* + * tt588_set_split_mode + * assumes rig!=NULL + */ +int tt588_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) +{ + // VFOB is the split VFO + return tt588_set_mode(rig, RIG_VFO_B, tx_mode, tx_width); +} + +/* + * tt588_get_split_mode + * assumes rig!=NULL, tx_mode!=NULLm, tx_width!=NULL + */ +int tt588_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) +{ + // VFOB is the split VFO + return tt588_get_mode(rig, RIG_VFO_B, tx_mode, tx_width); +} + /* * tt588_get_mode * Assumes rig!=NULL, mode!=NULL @@ -393,17 +517,23 @@ int tt588_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) unsigned char cmdbuf[16], respbuf[32]; char ttmode; - /* Query mode */ + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + // Query mode cmd_len = sprintf((char *) cmdbuf, "?M" EOM); - resp_len = 32; + resp_len = 4; retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) respbuf, &resp_len); - + if (resp_len > 4) { + resp_len = 4; + respbuf[4] = 0; + } if (retval != RIG_OK) return retval; if (respbuf[0] != 'M' || resp_len != 4) { - rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", - __FUNCTION__, respbuf); + rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __FUNCTION__, respbuf); return -RIG_EPROTO; } @@ -415,8 +545,7 @@ int tt588_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) ttmode = respbuf[2]; break; default: - rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", - __FUNCTION__, rig_strvfo(vfo)); + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); return -RIG_EINVAL; break; } @@ -426,24 +555,23 @@ int tt588_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) case TT588_USB: *mode = RIG_MODE_USB; break; case TT588_LSB: *mode = RIG_MODE_LSB; break; case TT588_CW: *mode = RIG_MODE_CW; break; + case TT588_CWR: *mode = RIG_MODE_CWR; break; case TT588_FM: *mode = RIG_MODE_FM; break; default: - rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", - __FUNCTION__, ttmode); + rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __FUNCTION__, ttmode); return -RIG_EPROTO; } /* Query passband width (filter) */ cmd_len = sprintf((char *) cmdbuf, "?W" EOM); - resp_len = 32; + resp_len = 3; retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) respbuf, &resp_len); if (retval != RIG_OK) return retval; if (respbuf[0] != 'W' && resp_len != 3) { - rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", - __FUNCTION__, respbuf); + rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __FUNCTION__, respbuf); return -RIG_EPROTO; } @@ -487,10 +615,10 @@ int tt588_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) case 36: *width = 250; break; case 37: *width = 200; break; default: - rig_debug(RIG_DEBUG_ERR, "%s: unexpected bandwidth '%c'\n", - __FUNCTION__, respbuf[1]); + rig_debug(RIG_DEBUG_ERR, "%s: unexpected bandwidth '%c'\n", __FUNCTION__, respbuf[1]); return -RIG_EPROTO; } + rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%d width=%d\n", __FUNCTION__, rig_strvfo(vfo),*mode,*width); return RIG_OK; } @@ -518,15 +646,20 @@ int tt588_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) struct tt588_priv_data *priv = (struct tt588_priv_data *) rig->state.priv; + rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%d width=%d\n", __FUNCTION__, rig_strvfo(vfo),mode,width); + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + /* Query mode for both VFOs. */ cmd_len = sprintf((char *) cmdbuf, "?M" EOM); - resp_len = 32; + resp_len = 4; retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) respbuf, &resp_len); if (retval != RIG_OK) return retval; - if (respbuf[0] != 'M' || resp_len != 4) { - rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", - __FUNCTION__, respbuf); + if (respbuf[0] != 'M' || respbuf[3] != 0x0d) { + rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __FUNCTION__, respbuf); return -RIG_EPROTO; } @@ -534,11 +667,11 @@ int tt588_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) case RIG_MODE_USB: ttmode = TT588_USB; break; case RIG_MODE_LSB: ttmode = TT588_LSB; break; case RIG_MODE_CW: ttmode = TT588_CW; break; + case RIG_MODE_CWR: ttmode = TT588_CWR; break; case RIG_MODE_AM: ttmode = TT588_AM; break; case RIG_MODE_FM: ttmode = TT588_FM; break; default: - rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %d\n", - __FUNCTION__, mode); + rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %d\n", __FUNCTION__, mode); return -RIG_EINVAL; } @@ -553,8 +686,7 @@ int tt588_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) cmd_len = sprintf((char *) cmdbuf, "*M%c%c" EOM, respbuf[1], ttmode); break; default: - rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", - __FUNCTION__, rig_strvfo(vfo)); + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); return -RIG_EINVAL; } @@ -579,74 +711,60 @@ int tt588_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) */ int tt588_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { - char sunits[6]; - float fwd, refl, sstr; + float fwd, refl; int retval, cmd_len, lvl_len; unsigned char cmdbuf[16],lvlbuf[32]; + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } - /* Optimize: - * sort the switch cases with the most frequent first - */ switch (level) { case RIG_LEVEL_SWR: - /* Get forward power. */ - lvl_len = 32; - retval = tt588_transaction (rig, "?F" EOM, 3, (char *) lvlbuf, &lvl_len); + lvl_len = 4; + retval = tt588_transaction (rig, "?S" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) return retval; - if (lvlbuf[0] != 'F' || lvl_len != 3) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); + // top bit of lvlbuf[1] should be on if transmitting + if (lvlbuf[0] != 'S' || lvl_len != 4 || lvlbuf[3] != 0x0d || ((lvlbuf[1]&0x80)==0)) { + val->f = 99; // infinity + rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer len=%d buf=%02x %02x %02x %02x\n", + __FUNCTION__, lvl_len,lvlbuf[0],lvlbuf[1],lvlbuf[2],lvlbuf[3]); return -RIG_EPROTO; } - fwd = (float) lvlbuf[1]; - - /* Get reflected power. */ - lvl_len = 32; - retval = tt588_transaction (rig, "?R" EOM, 3, (char *) lvlbuf, &lvl_len); - if (retval != RIG_OK) - return retval; - if (lvlbuf[0] != 'R' || lvl_len != 3) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); - return -RIG_EPROTO; + /* forward power. */ + fwd = (float) (lvlbuf[1]&0x7f); + /* reflected power. */ + refl = (float) lvlbuf[2]; + if (fwd > 0) { + val->f = refl/fwd; // our ratio + val->f = (1+val->f)/(1-val->f); // SWR formula + } + else { + val->f = 99; } - refl = (float) lvlbuf[1]; - - val->f = fwd/refl; break; case RIG_LEVEL_STRENGTH: + lvl_len = 6; retval = tt588_transaction (rig, "?S" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) return retval; if (lvlbuf[0] != 'S' || lvl_len != 6) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); + rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", __FUNCTION__, lvlbuf); return -RIG_EPROTO; } - /* Reply in the form S0944 for 44 dB over S9 */ - /* TODO: check whether in RX or TX mode */ - val->i = (int)lvlbuf[2] * 6 - 54 + lvlbuf[3]*10 + lvlbuf[4]; - - break; - - case RIG_LEVEL_RFPOWER: - - /* Get forward power in volts. */ - lvl_len = 32; - retval = tt588_transaction (rig, "?P" EOM, 3, (char *) lvlbuf, &lvl_len); - if (retval != RIG_OK) - return retval; - if (lvlbuf[0] != 'P' || lvl_len != 4) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); - return -RIG_EPROTO; + // Reply in the form S0944 for 44 dB over S9 in ASCII + // S9=0db S0=-54dB + if ((lvlbuf[1]&0x80)==0) { // then we're not in transmit mode so we're good + val->i = (int)((lvlbuf[2]-'0') * 6 - 54)+ (lvlbuf[3]-'0')*10 + (lvlbuf[4]-'0'); + } + else { + val->i = 0; // we'll just return SWR=0 if transmit is on } - val->f = 100 * (float) lvlbuf[1] / 0xff; break; @@ -654,22 +772,22 @@ int tt588_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) /* Read rig's AGC level setting. */ cmd_len = sprintf((char *) cmdbuf, "?G" EOM); - lvl_len = 32; + lvl_len = 3; retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) return retval; - if (lvlbuf[0] != 'G' || lvl_len != 3) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); + + if (lvlbuf[0] != 'G' || lvl_len != 3 || lvlbuf[2] != 0x0d) { + rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", __FUNCTION__, lvlbuf); return -RIG_EPROTO; } switch(lvlbuf[1]) { - case '0': val->i=RIG_AGC_OFF; break; - case '1': val->i=RIG_AGC_SLOW; break; - case '2': val->i=RIG_AGC_MEDIUM; break; - case '3': val->i=RIG_AGC_FAST; break; - default: return -RIG_EPROTO; + case '0': val->i=RIG_AGC_OFF; break; + case '1': val->i=RIG_AGC_SLOW; break; + case '2': val->i=RIG_AGC_MEDIUM; break; + case '3': val->i=RIG_AGC_FAST; break; + default: return -RIG_EPROTO; } break; @@ -677,14 +795,13 @@ int tt588_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) /* Volume returned as single byte. */ cmd_len = sprintf((char *) cmdbuf, "?U" EOM); - lvl_len = 32; + lvl_len = 3; retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) return retval; - if (lvlbuf[0] != 'U' || lvl_len != 3) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); + if (lvlbuf[0] != 'U' || lvlbuf[2] != 0x0d) { + rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", __FUNCTION__, lvlbuf); return -RIG_EPROTO; } @@ -692,120 +809,80 @@ int tt588_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; case RIG_LEVEL_IF: -#if 0 -NO IF MONITOR?? - cmd_len = sprintf((char *) cmdbuf, "?R%cP" EOM, - which_receiver(rig, vfo)); - - retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) lvlbuf, &lvl_len); - if (retval != RIG_OK) - return retval; - - if (lvlbuf[1] != 'R' || lvlbuf[3] != 'P' || lvl_len < 5) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); - return -RIG_EPROTO; - } - - val->i = atoi(lvlbuf+4); -#endif + // Omni VII has so such thing + rig_debug(RIG_DEBUG_ERR,"%s: no RIG_LEVEL_IF on Omni VII\n", __FUNCTION__); val->i = 0; break; case RIG_LEVEL_RF: - cmd_len = sprintf((char *) cmdbuf, "?I" EOM); - lvl_len = 32; + lvl_len = 3; retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) return retval; - if (lvlbuf[0] != 'I' || lvl_len != 3) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); + if (lvlbuf[0] != 'I' || lvlbuf[2] != 0x0d) { + rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", __FUNCTION__, lvlbuf); return -RIG_EPROTO; } - val->f = 1 - (float) lvlbuf[1] / 0xff; + val->f = lvlbuf[1]/127.0f; break; case RIG_LEVEL_ATT: cmd_len = sprintf((char *) cmdbuf, "?J" EOM); - lvl_len = 32; + lvl_len = 33; retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) return retval; - if (lvlbuf[0] != 'J' || lvl_len != 3) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); + if (lvlbuf[0] != 'J' || lvlbuf[2] != 0x0d) { + rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", __FUNCTION__, lvlbuf); return -RIG_EPROTO; } - val->i = lvlbuf[1]; + val->i = (lvlbuf[1]-'0')*6; // 1=6, 2=12, 3=18 break; +#if 0 case RIG_LEVEL_PREAMP: - /* Receiver does not contain a preamp */ + /* Only in remote mode */ val->i=0; break; +#endif case RIG_LEVEL_SQL: cmd_len = sprintf((char *) cmdbuf, "?H" EOM); - lvl_len = 32; + lvl_len = 3; retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) return retval; - if (lvlbuf[0] != 'H' || lvl_len != 3) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); + if (lvlbuf[0] != 'H' || lvlbuf[2] != 0x0d) { + rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", __FUNCTION__, lvlbuf); return -RIG_EPROTO; } - val->f = ((float) lvlbuf[1] / 127); + val->f = lvlbuf[1] / 127.0f; break; +#if 0 case RIG_LEVEL_MICGAIN: - - lvl_len = 3; - retval = tt588_transaction (rig, "?O" EOM, 3, (char *) lvlbuf, &lvl_len); - if (retval != RIG_OK) - return retval; - - if (lvlbuf[0] != 'O' || lvl_len != 3) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); - return -RIG_EPROTO; - } - - val->f = (float) lvlbuf[2] / 0x0f; + /* Only in remote mode */ + val->i=0; break; +#endif +#if 0 case RIG_LEVEL_COMP: - /* Query S units signal level. */ - lvl_len = 32; - retval = tt588_transaction (rig, "?S" EOM, 3, (char *) lvlbuf, &lvl_len); - if (retval != RIG_OK) - return retval; - - if (lvlbuf[0] != 'S' || lvl_len != 6) { - rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n", - __FUNCTION__, lvlbuf); - return -RIG_EPROTO; - } - - sprintf((char *) sunits, "%c%c.%c%c", - lvlbuf[1], lvlbuf[2], lvlbuf[3], lvlbuf[4]); - sscanf(sunits, "%f", &sstr); -printf("%f\n", sstr); - val->f = sstr; + /* Only in remote mode */ + val->i=0; break; - +#endif default: - rig_debug(RIG_DEBUG_ERR,"%s: unsupported level %d\n", - __FUNCTION__, level); + rig_debug(RIG_DEBUG_ERR,"%s: unsupported level %d\n", __FUNCTION__, level); return -RIG_EINVAL; } + rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s level=%d val=%d\n", __FUNCTION__, rig_strvfo(vfo),level,*val); return RIG_OK; } @@ -816,9 +893,14 @@ printf("%f\n", sstr); */ int tt588_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { - int retval, cmd_len; + int retval, cmd_len,ii; unsigned char cmdbuf[16], agcmode; + rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s level=%d val=%d\n", __FUNCTION__, rig_strvfo(vfo),level,val); + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } switch (level) { case RIG_LEVEL_AF: @@ -834,7 +916,7 @@ int tt588_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) case RIG_LEVEL_RF: /* RF gain. Omni-VII expects value 0 for full gain, and 127 for lowest gain */ - cmd_len = sprintf((char *) cmdbuf, "*I%c" EOM, (char)(127- val.f * 127)); + cmd_len = sprintf((char *) cmdbuf, "*I%c" EOM, 127-(char)(val.f * 127)); retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, NULL, NULL); if (retval != RIG_OK) return retval; @@ -851,19 +933,316 @@ int tt588_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) default: return -RIG_EINVAL; } - cmd_len = sprintf((char *) cmdbuf, "*G%c" EOM, agcmode); + cmd_len = sprintf((char *) cmdbuf, "*Gx" EOM); + cmdbuf[2] = agcmode; retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, NULL, NULL); if (retval != RIG_OK) return retval; break; + case RIG_LEVEL_ATT: + /* Attenuation */ + ii = -1; /* Request 0-5 dB -> 0, 6-11 dB -> 6, etc. */ + while ( rig->caps->attenuator[++ii] != RIG_DBLST_END ) { + if (rig->caps->attenuator[ii] > val.i) break; + } + cmd_len = sprintf((char *) cmdbuf, "*J%c" EOM, ii+'0'); + retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, NULL, NULL); + if (retval != RIG_OK) + return retval; + + break; + + case RIG_LEVEL_SQL: + /* Squelch level, float 0.0 - 1.0 */ + cmd_len = sprintf((char *) cmdbuf, "*H%c" EOM,(int)(val.f*127)); + retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, NULL, NULL); + if (retval != RIG_OK) + return retval; + break; + default: - rig_debug(RIG_DEBUG_ERR,"%s: unsupported level %d\n", - __FUNCTION__, level); + rig_debug(RIG_DEBUG_ERR,"%s: unsupported level %d\n", __FUNCTION__, level); return -RIG_EINVAL; } return RIG_OK; } +/* + * tt588_set_split_vfo + * Assumes rig!=NULL + */ +int tt588_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) +{ + int retval, cmd_len, resp_len; + char cmdbuf[16],respbuf[16]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s split=%d tx_vfo=%s\n", __FUNCTION__, rig_strvfo(vfo),split,rig_strvfo(tx_vfo)); + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + + cmd_len = sprintf(cmdbuf,"*Nx" EOM "?N" EOM); + //if (split == RIG_SPLIT_ON || tx_vfo==RIG_VFO_B) + if (split == RIG_SPLIT_ON) + cmdbuf[2] = 1; + else + cmdbuf[2] = 0; + + resp_len = 3; + retval = tt588_transaction( rig, cmdbuf, cmd_len, respbuf, &resp_len ); + + if (retval != RIG_OK) + return retval; + if (respbuf[0] != 'N' || respbuf[2] != 0x0d) { + rig_debug(RIG_DEBUG_ERR,"%s: unknown response to *N%d='%s'\n", __FUNCTION__,split,respbuf); + return -RIG_EINVAL; + } + return RIG_OK; +} + +/* + * tt588_get_split_vfo + * Assumes rig!=NULL, split!=NULL, tx_vfo!=NULL + */ +int tt588_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) +{ + int cmd_len, resp_len, retval; + char cmdbuf[16], respbuf[16]; + + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + + // get split on/off + cmd_len = sprintf(cmdbuf,"?N" EOM); + resp_len = 3; + retval = tt588_transaction (rig, cmdbuf, cmd_len, respbuf, &resp_len); + if (resp_len != 3) { + rig_debug(RIG_DEBUG_ERR,"%s: bad response length, expected %d, got %d\n", __FUNCTION__,3,resp_len); + } + // respbuf returns "N0" or "N1" for split off/on + if (retval != RIG_OK) + return retval; + + if (respbuf[0] != 'N' || respbuf[2] != 0x0d || (respbuf[1]!=0 && respbuf[1]!=1)) + return -RIG_EPROTO; + + *split = respbuf[1] == 0 ? RIG_SPLIT_OFF : RIG_SPLIT_ON; + if (*split == RIG_SPLIT_ON) + *tx_vfo = RIG_VFO_B; // Omni VII always transmits on VFO_B when in split + else + *tx_vfo = RIG_VFO_A; // VFO A when not in split + + rig_debug(RIG_DEBUG_VERBOSE,"%s: split=%d tx_vfo=%s\n", __FUNCTION__,*split,rig_strvfo(*tx_vfo)); + + return RIG_OK; +} + +/* + * tt588_set_ptt + * Assumes rig!=NULL + */ +int tt588_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) +{ + int retval, cmd_len; + char cmdbuf[32]; + + rig_debug(RIG_DEBUG_VERBOSE,"%s: ptt=%d\n", __FUNCTION__,ptt); + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + + cmd_len = sprintf(cmdbuf,"*Txx" EOM); + cmdbuf[3]=0; + if (ptt) { + cmdbuf[2]=4; + } + else { + cmdbuf[2]=0; + } + retval = tt588_transaction (rig, cmdbuf, cmd_len, NULL, 0); // no response + if (retval != RIG_OK) + return retval; + + return RIG_OK; +} + +/* + * tt588_get_info + * Assumes rig!=NULL + * Returns statically allocated buffer + */ +const char *tt588_get_info(RIG *rig) +{ + static char cmdbuf[16],firmware[64]; + int cmd_len, firmware_len, retval; + + cmd_len = sprintf(cmdbuf,"?V" EOM); + memset(firmware,0,sizeof(firmware)); + firmware_len = sizeof(firmware); + rig_debug(RIG_DEBUG_VERBOSE,"%s: firmware_len=%d\n", __FUNCTION__,firmware_len); + retval = tt588_transaction (rig, cmdbuf, cmd_len, firmware, &firmware_len); + + // Response should be "VER 1010-588 " plus "RADIO x\r" or "REMOTEx\r" + // if x=blank ham band transmit only + // if x='M' MARS transmit only + if (retval != RIG_OK) { + rig_debug(RIG_DEBUG_ERR,"%s: ack NG, len=%d\n", __FUNCTION__, firmware_len); + return NULL; + } + rig_debug(RIG_DEBUG_VERBOSE,"%s: %s\n", __FUNCTION__,firmware); + return firmware; +} + +/* + * tt588_get_xit + * tt588_get_rit is linked to this too since it's just one offset and the same command + * Assumes rig!=NULL + * Note that ?L can't query RIT/XIT separately...there's only one offset + */ +int tt588_get_xit(RIG * rig, vfo_t vfo, shortfreq_t *xit) +{ + int cmd_len, resp_len, retval; + char cmdbuf[16], respbuf[16]; + + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + + // get xit + cmd_len = sprintf(cmdbuf,"?L" EOM); + resp_len = 5; + retval = tt588_transaction (rig, cmdbuf, cmd_len, respbuf, &resp_len); + if (resp_len != 5) { + rig_debug(RIG_DEBUG_ERR,"%s: bad response length, expected %d, got %d\n", __FUNCTION__,5,resp_len); + } + if (retval != RIG_OK) + return retval; + + if (respbuf[0] != 'L' || respbuf[4] != 0x0d) + return -RIG_EPROTO; + *xit = (respbuf[2]*(short)256) | respbuf[3]; + rig_debug(RIG_DEBUG_VERBOSE,"%s: rit=%d\n", __FUNCTION__,*xit); + + return RIG_OK; +} + +// This routine handles both rit and xit setting +// Though we can turn on both (which=3) there's no obvious condition for doing so +// We can only query the one offset and don't really know for which it was set +// And is there any reason to turn on both? If so, hamblib doesn't seem to support that. +// +static int set_rit_xit(RIG * rig, vfo_t vfo, shortfreq_t rit, int which) +{ + int retval, cmd_len; + char cmdbuf[16]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s: rit=%d\n", __FUNCTION__, rit); + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + + // For some reason need an extra \r on here + // This is with version 1.036 -- it appears to want 7 chars instead of 6 + cmd_len = sprintf(cmdbuf,"*Lxxx" EOM EOM); + cmdbuf[2] = which; // set xit bit. 0=off,1=rit, 2=xit, 3=both + cmdbuf[3] = rit>>8; + cmdbuf[4] = rit&0xff; + retval = tt588_transaction( rig, cmdbuf, cmd_len, NULL, 0 ); // no response + + if (retval != RIG_OK) + return retval; + return RIG_OK; +} + +/* + * tt588_set_xit + * Assumes rig!=NULL + */ +int tt588_set_xit(RIG * rig, vfo_t vfo, shortfreq_t xit) +{ + return set_rit_xit(rig,vfo,xit,2); // bit 2 is xit +} + +/* + * tt588_set_xit + * Assumes rig!=NULL + */ +int tt588_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit) +{ + return set_rit_xit(rig,vfo,rit,1); // bit 1 is rit +} + +#if 0 // commenting out prototypes that are only for remote use +/* + * This is a prototype function as C1V is only available in remote mode + * tt588_get_ant + * Assumes rig!=NULL + */ +int tt588_get_ant(RIG * rig, vfo_t vfo, ant_t *ant) +{ + int cmd_len, resp_len, retval; + char cmdbuf[16], respbuf[16]; + + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + + // get xit + cmd_len = sprintf(cmdbuf,"*C1V" EOM); + resp_len = 5; + // this should be the only line needing change for remote operation + retval = tt588_transaction (rig, cmdbuf, cmd_len, respbuf, &resp_len); + if (resp_len != 5) { + rig_debug(RIG_DEBUG_ERR,"%s: bad response length, expected %d, got %d\n", __FUNCTION__,5,resp_len); + } + if (retval != RIG_OK) + return retval; + + if (respbuf[0] != 'C' || respbuf[4] != 0x0d) + return -RIG_EPROTO; + *ant = respbuf[3]; + rig_debug(RIG_DEBUG_VERBOSE,"%s: rit=%d\n", __FUNCTION__,*ant); + + return RIG_OK; +} + +/* + * This is a prototype function as C1V is only available in remote mode + * tt588_set_ant + * Assumes rig!=NULL + */ +int tt588_set_ant(RIG * rig, vfo_t vfo, ant_t ant) +{ + int retval, cmd_len; + char cmdbuf[16]; + + if(check_vfo(vfo)==FALSE) { + rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n", __FUNCTION__, rig_strvfo(vfo)); + return -RIG_EINVAL; + } + rig_debug(RIG_DEBUG_VERBOSE, "%s: ant=%d\n", __FUNCTION__, ant); + + cmd_len = sprintf(cmdbuf,"*C1Vx" EOM); + // 0 = RX=TX=ANT1 + // 1 = RX=TX=ANT2 + // 2 = RX=RXAUX, TX=ANT1 + // 3 = RX=RXAUC, TX=ANT2 + cmdbuf[4] = ant; + // this should be the only line needing change for remote operation + retval = tt588_transaction( rig, cmdbuf, cmd_len, NULL, 0 ); // no response + + if (retval != RIG_OK) + return retval; + return RIG_OK; +} +#endif