The attached omnivii.c and the serial patch you sent me and the resulting
1.5 head version r4635 works on Windows 7, Windows 10 9879, and Bert Hyman
W0RSB reports it works for him too.
I'm running the latest Log4OM, JTAlert, and HRD 6 beta on Windows 10 which
I've found runs 98% of all software that I've thrown at it so far.  Very
backwards compatible even on device drivers for FTDI and the Prolific 3.2
driver and such.
The only annoyance with wsjt-x on Windows 10 is the "Untested Windows
version 6.4 detected".
I may try testing a newer QT next and see if I can get that error to go away
and how it works with wsjt-x.  I would think we might want to ensure the 1.5
version runs cleanly on Windows 10 without that warning message so is
upgrading QT in the plans?

I also sent this file to John Nelson G4KLA who is building a Mac version for
a guy he knows who has the Omni VII on a Mac.  
So should have some confirmation for Mac in the next few days hopefully.

I'm running this in fake split mode and with CAT PTT successfully.

And on side note I also tested 1.5 with Omnirig and it works with the Omni
VII just fine too...had problems before that I never followed up on.

Mike W9MDB

/*
 *  Hamlib TenTenc backend - TT-588 description
 *  Copyright (c) 2003-2009 by Stephane Fillod
 *  Modifications 2014 by Michael Black W9MDB
 *
 *
 *   This library is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *   Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <serial.h>
#include <hamlib/rig.h>
#include "tentec.h"
#include "tentec2.h"
#include "bandplan.h"

struct tt588_priv_data {
        int ch;     /* mem */
        vfo_t vfo_curr;
};


#define TT588_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|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_ANTS (RIG_ANT_1|RIG_ANT_2)

#define TT588_PARMS (RIG_PARM_NONE)

#define TT588_VFO (RIG_VFO_A|RIG_VFO_B)

#define TT588_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO)

#define TT588_AM  '0'
#define TT588_USB '1'
#define TT588_LSB '2'
#define TT588_CW  '3'
#define TT588_FM  '4'
#define EOM "\015"      /* CR */

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_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);
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_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);

/*
 * 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.
 */
const struct rig_caps tt588_caps = {
.rig_model =  RIG_MODEL_TT588,
.model_name = "TT-588 Omni VII",
.mfg_name =  "Ten-Tec",
.version =  "0.3",
.copyright =  "LGPL",
.status =  RIG_STATUS_ALPHA,
.rig_type =  RIG_TYPE_TRANSCEIVER,
.ptt_type =  RIG_PTT_RIG,
.dcd_type =  RIG_DCD_NONE,
.port_type =  RIG_PORT_SERIAL,
.serial_rate_min =  57600,
.serial_rate_max =  57600,
.serial_data_bits =  8,
.serial_stop_bits =  1,
.serial_parity =  RIG_PARITY_NONE,
.serial_handshake =  RIG_HANDSHAKE_HARDWARE,
.write_delay =  0,
.post_write_delay =  0,
.timeout =  400,
.retry =  3,

.has_get_func =  TT588_FUNCS,
.has_set_func =  TT588_FUNCS,
.has_get_level =  TT588_LEVELS,
.has_set_level =  RIG_LEVEL_SET(TT588_LEVELS),
.has_get_parm =  TT588_PARMS,
.has_set_parm =  TT588_PARMS,
.level_gran =  {},                 /* FIXME: granularity */
.parm_gran =  {},
.ctcss_list =  NULL,
.dcs_list =  NULL,
.preamp =   { 10, RIG_DBLST_END }, /* FIXME: real value */
.attenuator =   { 15, RIG_DBLST_END },
.max_rit =  Hz(8192),
.max_xit =  Hz(8192),
.max_ifshift =  kHz(2),
.targetable_vfo =  RIG_TARGETABLE_FREQ|RIG_TARGETABLE_MODE,
.transceive =  RIG_TRN_OFF,
.bank_qty =   0,
.chan_desc_sz =  0,

.chan_list =  {
                {   0, 127, RIG_MTYPE_MEM, TT_MEM_CAP },
                },

.rx_range_list1 =  {
        {kHz(500),MHz(30),TT588_RXMODES,-1,-1,TT588_VFO,TT588_ANTS},
        {MHz(48),MHz(54),TT588_RXMODES,-1,-1,TT588_VFO,TT588_ANTS},
        RIG_FRNG_END,
  },
.tx_range_list1 =  {
        FRQ_RNG_HF(1,TT588_MODES, W(5),W(100),TT588_VFO,TT588_ANTS),
        FRQ_RNG_6m(1,TT588_MODES, W(5),W(100),TT588_VFO,TT588_ANTS),
        RIG_FRNG_END,
  },

.rx_range_list2 =  {
        {kHz(500),MHz(30),TT588_RXMODES,-1,-1,TT588_VFO,TT588_ANTS},
        {MHz(48),MHz(54),TT588_RXMODES,-1,-1,TT588_VFO,TT588_ANTS},
        RIG_FRNG_END,
  },
.tx_range_list2 =  {
        FRQ_RNG_HF(2,TT588_MODES, W(5),W(100),TT588_VFO,TT588_ANTS),
        {MHz(5.25),MHz(5.40),TT588_MODES,W(5),W(100),TT588_VFO,TT588_ANTS},
        FRQ_RNG_6m(2,TT588_MODES, W(5),W(100),TT588_VFO,TT588_ANTS),
        RIG_FRNG_END,
  },

.tuning_steps =  {
         {TT588_RXMODES,1},
         {TT588_RXMODES,10},
         {TT588_RXMODES,100},
         {TT588_RXMODES,kHz(1)},
         {TT588_RXMODES,kHz(10)},
         {TT588_RXMODES,kHz(100)},
         RIG_TS_END,
        },
        /* 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_FM, kHz(15)}, /* TBC */
                RIG_FLT_END,
        },
.priv =  (void*) NULL,

.rig_init =  tt588_init,
.set_freq =  tt588_set_freq,
.get_freq =  tt588_get_freq,
.set_vfo =  tt588_set_vfo,
.get_vfo =  tt588_get_vfo,
.set_mode =  tt588_set_mode,
.get_mode =  tt588_get_mode,
.get_level =  tt588_get_level,
.set_level =  tt588_set_level,
.set_split_vfo =  tt588_set_split_vfo,
.get_split_vfo =  tt588_get_split_vfo,
.set_ptt =  tt588_set_ptt,
.reset =  tt588_reset,
.get_info =  tt588_get_info,

};

/* Filter table for 588 reciver support. */
static int tt588_rxFilter[] = {
  12000, 9000, 8000, 7500, 7000, 6500, 6000, 5500, 5000, 4500, 4000, 3800, 
3600, 3400, 3200,
  3000, 2800, 2600, 2500, 2400, 2200, 2000, 1800, 1600, 1400,
  1200, 1000, 900, 800, 700, 600, 500, 450, 400, 350, 300, 250, 200
};

/*
 * Function definitions below
 */

/* 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. */
// 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)
{
        int     i, retval;
        struct  rig_state *rs = &rig->state;

        // 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);

                // 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 \r so 
that is our stop char
                        char *term="\r";
                        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\r", 3); // we wont' worry about 
the response here
                retval = read_string(&rs->rigport, xxbuf, sizeof(xxbuf), "", 
0); // this should timeout
                if (retval != RIG_OK) 
                        rig_debug(RIG_DEBUG_ERR,"%s: XX command failed, 
try#%d\n",__FUNCTION__, i+1);
        }
        return retval;
}

/*
 * tt588_init:
 * Basically, it just sets up *priv
 */
int tt588_init(RIG *rig)
{
        struct tt588_priv_data *priv;

        priv = (struct tt588_priv_data *) malloc(sizeof(struct 
tt588_priv_data));
        if (!priv) {
                /* whoops! memory shortage! */
                return -RIG_ENOMEM;
        }

        memset(priv, 0, sizeof(struct tt588_priv_data));

        /*
         * set arbitrary initial status
         */
        priv->ch = 0;
        priv->vfo_curr = RIG_VFO_A;
        rig->state.priv = (rig_ptr_t)priv;

        return RIG_OK;
}

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;
        }
}

int tt588_get_vfo(RIG *rig, vfo_t *vfo) {

        struct tt588_priv_data *priv = (struct tt588_priv_data *) 
rig->state.priv;
        *vfo = priv->vfo_curr;
        return RIG_OK;
}

/*
 * tt588_set_vfo
 * Assumes rig!=NULL
 */
int tt588_set_vfo(RIG *rig, vfo_t vfo)
{
        struct tt588_priv_data *priv = (struct tt588_priv_data 
*)rig->state.priv;

        if (vfo == RIG_VFO_CURR)
                return RIG_OK;

        priv->vfo_curr = vfo;
        return RIG_OK;
}

/*
 * Software restart
 */
int tt588_reset(RIG *rig, reset_t reset) {
        int retval, reset_len;
        char reset_buf[32];

        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);
                return -RIG_EPROTO;
        }

        return RIG_OK;
}

/*
 * tt588_get_freq
 * Assumes rig!=NULL, freq!=NULL
 */
int tt588_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) {

        int cmd_len, resp_len, retval;
        unsigned char cmdbuf[16], respbuf[32];

        //cmd_len = sprintf((char *) cmdbuf, "?%c" EOM,which_vfo(rig,vfo));
        // we only worry about VFO A as we can only fake split
        cmd_len = sprintf((char *) cmdbuf, "?A" EOM);
        resp_len = 6;
        retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, (char *) 
respbuf, &resp_len);
        if (retval != RIG_OK)
                return retval;

        if (resp_len != 6) {
                rig_debug(RIG_DEBUG_ERR, "%s: unexpected length '%d'\n",
                        __FUNCTION__, resp_len);
                //return -RIG_EPROTO;
        }
        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;
        }
        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;
        unsigned char cmdbuf[16];

        /* Freq is 4 bytes long, MSB sent first. */
        bytes[3] = ((int) freq >> 24) & 0xff;
        bytes[2] = ((int) freq >> 16) & 0xff;
        bytes[1] = ((int) freq >>  8) & 0xff;
        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]);

        return tt588_transaction(rig, (char *) cmdbuf, cmd_len, NULL, NULL);
}

/*
 * tt588_get_mode
 * Assumes rig!=NULL, mode!=NULL
 */
int tt588_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
{
        int cmd_len, resp_len, retval;
        unsigned char cmdbuf[16], respbuf[32];
        char ttmode;

        /* Query mode */
        cmd_len = sprintf((char *) cmdbuf, "?M" EOM);
        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);
                return -RIG_EPROTO;
        }

        switch (which_vfo(rig, vfo)) {
        case 'A':
                ttmode = respbuf[1];
                break;
        case 'B':
                ttmode = respbuf[2];
                break;
        default:
                rig_debug(RIG_DEBUG_ERR,"%s: unsupported VFO %s\n",
                        __FUNCTION__, rig_strvfo(vfo));
                return -RIG_EINVAL;
                break;
        }

        switch (ttmode) {
        case TT588_AM:  *mode = RIG_MODE_AM;  break;
        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_FM: *mode = RIG_MODE_FM;  break;
        default:
                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 = 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);
                return -RIG_EPROTO;
        }

        switch (respbuf[1]) {
        case 0: *width = 12000; break;
        case 1: *width = 9000; break;
        case 2: *width = 8000; break;
        case 3: *width = 7500; break;
        case 4: *width = 7000; break;
        case 5: *width = 6500; break;
        case 6: *width = 6000; break;
        case 7: *width = 5500; break;
        case 8: *width = 5000; break;
        case 9: *width = 4500; break;
        case 10: *width = 4000; break;
        case 11: *width = 3800; break;
        case 12: *width = 3600; break;
        case 13: *width = 3400; break;
        case 14: *width = 3200; break;
        case 15: *width = 3000; break;
        case 16: *width = 2800; break;
        case 17: *width = 2600; break;
        case 18: *width = 2500; break;
        case 19: *width = 2400; break;
        case 20: *width = 2200; break;
        case 21: *width = 2000; break;
        case 22: *width = 1800; break;
        case 23: *width = 1600; break;
        case 24: *width = 1400; break;
        case 25: *width = 1200; break;
        case 26: *width = 1000; break;
        case 27: *width = 900; break;
        case 28: *width = 800; break;
        case 29: *width = 700; break;
        case 30: *width = 600; break;
        case 31: *width = 500; break;
        case 32: *width = 450; break;
        case 33: *width = 400; break;
        case 34: *width = 350; break;
        case 35: *width = 300; break;
        case 36: *width = 250; break;
        case 37: *width = 200; break;
        default:
                rig_debug(RIG_DEBUG_ERR, "%s: unexpected bandwidth '%c'\n",
                        __FUNCTION__, respbuf[1]);
                return -RIG_EPROTO;
        }

        return RIG_OK;
}

/* Find rx filter index of bandwidth the same or larger as requested. */
static int tt588_filter_number(int width)
{
        int     i;

        for (i = 34; i >= 0; i--)
                if (width <= tt588_rxFilter[i])
                        return i;
        return 0; /* Widest filter, 8 kHz. */
}


/*
 * tt588_set_mode
 * Assumes rig!=NULL
 */
int tt588_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
{
        unsigned char cmdbuf[32], respbuf[32], ttmode;
        int cmd_len, resp_len, retval;

        struct tt588_priv_data *priv = (struct tt588_priv_data *) 
rig->state.priv;

        /* Query mode for both VFOs. */
        cmd_len = sprintf((char *) cmdbuf, "?M" EOM);
        resp_len = 32;
        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);
                return -RIG_EPROTO;
        }

        switch (mode) {
        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_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);
                return -RIG_EINVAL;
        }

        /* Set mode for both VFOs. */
        if (vfo == RIG_VFO_CURR)
                vfo = priv->vfo_curr;
        switch (vfo) {
        case RIG_VFO_A:
                cmd_len = sprintf((char *) cmdbuf, "*M%c%c" EOM, ttmode, 
respbuf[2]);
                break;
        case RIG_VFO_B:
                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));
                return -RIG_EINVAL;
        }

        retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, NULL, NULL);
        if (retval != RIG_OK)
                return retval;

        /* Set rx filter bandwidth. */

        if (width == RIG_PASSBAND_NORMAL)
                width = tt588_filter_number(rig_passband_normal(rig, mode));
        else
                width = tt588_filter_number((int) width);

        cmd_len = sprintf((char *) cmdbuf, "*W%c" EOM, (unsigned char) width);
        return tt588_transaction (rig, (char *) cmdbuf, cmd_len, NULL, NULL);
}

/*
 * tt588_get_level
 * Assumes rig!=NULL, val!=NULL
 */
int tt588_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
{
        char    sunits[6];
        float   fwd, refl, sstr;
        int retval, cmd_len, lvl_len;
        unsigned char cmdbuf[16],lvlbuf[32];


        /* 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);
                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);
                        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;
                }
                refl = (float) lvlbuf[1];

                val->f = fwd/refl;
                break;

        case RIG_LEVEL_STRENGTH:
                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;
                }

                /* 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;
                }
                val->f = 100 * (float) lvlbuf[1] / 0xff;

                break;

        case RIG_LEVEL_AGC:

                /* Read rig's AGC level setting. */
                cmd_len = sprintf((char *) cmdbuf, "?G" EOM);
                lvl_len = 32;
                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);
                        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;
                }
                break;

        case RIG_LEVEL_AF:

                /* Volume returned as single byte. */
                cmd_len = sprintf((char *) cmdbuf, "?U" EOM);
                lvl_len = 32;
                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);
                        return -RIG_EPROTO;
                }

                val->f = (float) lvlbuf[1] / 127;
                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
                val->i = 0;
                break;

        case RIG_LEVEL_RF:

                cmd_len = sprintf((char *) cmdbuf, "?I" EOM);
                lvl_len = 32;
                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);
                        return -RIG_EPROTO;
                }

                val->f = 1 - (float) lvlbuf[1] / 0xff;
                break;

        case RIG_LEVEL_ATT:

                cmd_len = sprintf((char *) cmdbuf, "?J" EOM);
                lvl_len = 32;
                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);
                        return -RIG_EPROTO;
                }
                val->i = lvlbuf[1];
                break;

        case RIG_LEVEL_PREAMP:
                /* Receiver does not contain a preamp */
                val->i=0;
                break;

        case RIG_LEVEL_SQL:

                cmd_len = sprintf((char *) cmdbuf, "?H" EOM);
                lvl_len = 32;
                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);
                        return -RIG_EPROTO;
                }
                val->f = ((float) lvlbuf[1] / 127);
                break;

        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;
                break;

        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;
                break;


        default:
                rig_debug(RIG_DEBUG_ERR,"%s: unsupported level %d\n",
                                __FUNCTION__, level);
                return -RIG_EINVAL;
        }

        return RIG_OK;
}

/*
 * tt588_set_level
 * Assumes rig!=NULL, val!=NULL
 */
int tt588_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
{
        int retval, cmd_len;
        unsigned char cmdbuf[16], agcmode;


        switch (level) {
        case RIG_LEVEL_AF:

                /* Volume */
                cmd_len = sprintf((char *) cmdbuf, "*U%c" EOM, (char)(val.f * 
127));
                retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, 
NULL, NULL);
                if (retval != RIG_OK)
                        return retval;

                break;

        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));
                retval = tt588_transaction (rig, (char *) cmdbuf, cmd_len, 
NULL, NULL);
                if (retval != RIG_OK)
                        return retval;

                break;

        case RIG_LEVEL_AGC:

                switch(val.i) {
                case RIG_AGC_OFF:    agcmode = '0'; break;
                case RIG_AGC_SLOW:   agcmode = '1'; break;
                case RIG_AGC_MEDIUM: agcmode = '2'; break;
                case RIG_AGC_FAST:   agcmode = '3'; break;
                default: return -RIG_EINVAL;
                }

                cmd_len = sprintf((char *) cmdbuf, "*G%c" EOM, agcmode);
                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);
                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)
{
#if 0
        int retval, cmd_len, resp_len;
        char cmdbuf[16],respbuf[16];

        // Omni VII always transmits on VFO A
        cmd_len = sprintf(cmdbuf,"*Nx\r");
        if (split == RIG_SPLIT_ON)
                cmdbuf[2] = 1;
        else
                cmdbuf[2] = 0;

        resp_len = 2;
        retval = tt588_transaction( rig, cmdbuf, cmd_len, respbuf, &resp_len );

        if (retval != RIG_OK)
                return retval;
        if (respbuf[1] != split) {
                rig_debug(RIG_DEBUG_ERR,"%s: unknown response to 
*N%d='%s'\n",__FUNCTION__,split,respbuf);
                return -RIG_EINVAL;
        }
#endif
        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; // keeping the warning for future 
reference
        char cmdbuf[16], respbuf[16];

        // get vfo
        *tx_vfo = 0; // Omni VII always transmits on just one VFO

        // get split
        cmd_len = sprintf(cmdbuf,"?N\r");
        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
        // only 2 bytes come back so we don't check here
        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;

        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];
        struct rig_state *rs = &rig->state;
        // we won't check for a response
        serial_flush(&rs->rigport);

        cmd_len = sprintf(cmdbuf,"*Txx\r");
        cmdbuf[3]=0;
        if (ptt) {
                cmdbuf[2]=4;
        }
        else {
                cmdbuf[2]=0;
        }
        retval = write_block(&rs->rigport, cmdbuf, cmd_len);
        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 buf[64];
        int firmware_len, retval;

        memset(buf,0,sizeof(buf));
        firmware_len = sizeof(buf);
        retval = tt588_transaction (rig, "?V\r", 3, buf, &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 || strncmp(buf,"VER 1010-588",12)!=0) {
                        rig_debug(RIG_DEBUG_ERR,"%s: ack NG, len=%d\n",
                                        __FUNCTION__, firmware_len);
                        return NULL;
        }
        return buf;
}
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
_______________________________________________
wsjt-devel mailing list
wsjt-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wsjt-devel

Reply via email to