diff --git a/kenwood/elecraft.h b/kenwood/elecraft.h index 62654f94c..52b30cb37 100644 --- a/kenwood/elecraft.h +++ b/kenwood/elecraft.h @@ -76,7 +76,7 @@ int elecraft_open(RIG *rig); * Table is RASTR value from SM command and dB relative to S9 == 0 * (see rig_get_level() in src/settings.c */ -#define K3_STR_CAL { 16, \ +#define K3_SM_CAL { 16, \ { \ { 0, -54 }, \ { 1, -42 }, \ @@ -97,4 +97,35 @@ int elecraft_open(RIG *rig); } } +/* K3 defines 100 values--0-100 in high resolution mode. + * Table is RASTR value from SMH command and dB relative to S9 == 0 + * (see rig_get_level() in src/settings.c + */ +#define K3_SMH_CAL { 22, \ + { \ + { 0, -54 }, \ + { 5, -48 }, \ + { 9, -42 }, \ + { 14, -36 }, \ + { 22, -30 }, \ + { 24, -24 }, \ + { 28, -18 }, \ + { 33, -12 }, \ + { 38, -6 }, \ + { 42, 0 }, \ + { 47, 5 }, \ + { 53, 10 }, \ + { 58, 15 }, \ + { 63, 20 }, \ + { 68, 25 }, \ + { 73, 30 }, \ + { 78, 35 }, \ + { 83, 40 }, \ + { 88, 45 }, \ + { 93, 50 }, \ + { 98, 55 }, \ + { 103, 60 }, \ + } } + + #endif /* _ELECRAFT_H */ diff --git a/kenwood/k3.c b/kenwood/k3.c index 031aa1187..d56bdb5e0 100644 --- a/kenwood/k3.c +++ b/kenwood/k3.c @@ -1,7 +1,7 @@ /* * Hamlib Kenwood backend - Elecraft K3 description * Copyright (c) 2002-2009 by Stephane Fillod - * Copyright (C) 2010 by Nate Bargmann, n0nb@arrl.net + * Copyright (C) 2010,2011 by Nate Bargmann, n0nb@arrl.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,6 +33,7 @@ #include "bandplan.h" #include "elecraft.h" #include "token.h" +#include "cal.h" #define K3_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_PKTUSB|\ @@ -69,6 +70,7 @@ int k3_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit); int k3_set_xit(RIG * rig, vfo_t vfo, shortfreq_t rit); int k3_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); int k3_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); +int k3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); /* Private helper functions */ @@ -91,7 +93,7 @@ const struct rig_caps k3_caps = { .rig_model = RIG_MODEL_K3, .model_name = "K3/KX3", .mfg_name = "Elecraft", - .version = "20110603", + .version = "20111122", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -183,7 +185,6 @@ const struct rig_caps k3_caps = { {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, - .str_cal = K3_STR_CAL, .priv = (void *)&k3_priv_caps, .rig_init = kenwood_init, @@ -211,7 +212,7 @@ const struct rig_caps k3_caps = { .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = kenwood_set_level, - .get_level = kenwood_get_level, + .get_level = k3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, .vfo_op = kenwood_vfo_op, @@ -423,11 +424,7 @@ int k3_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val) if (!rig) return -RIG_EINVAL; -// char buf[KENWOOD_MAX_BUF_LEN]; int err; -// const struct confparams *cfp; - -// cfp = rig_ext_lookup_tok(rig, token); switch(token) { case TOK_RIT_CLR: @@ -587,6 +584,67 @@ int k3_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width } +/* + * Handle S-meter (SM, SMH) level locally and pass rest to kenwood_get_level() + */ +int k3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !val) + return -RIG_EINVAL; + + char lvlbuf[50]; + int retval; + struct kenwood_priv_data *priv = rig->state.priv; + + switch (level) { + case RIG_LEVEL_STRENGTH: + /* As of FW rev 4.37 the K3 supports an 'SMH' command that + * offers a higher resolution, 0-100 (mine went to 106), + * rawstr value for more precise S-meter reporting. + */ + retval = strncmp(priv->k3_fw_rev, "4.37", 4); + if (retval < 0) { + cal_table_t str_cal = K3_SM_CAL; + + retval = kenwood_safe_transaction(rig, "SM", lvlbuf, 10, 7); + if (retval != RIG_OK) + return retval; + + sscanf(lvlbuf+2, "%d", &val->i); /* rawstr */ + + val->i = (int) rig_raw2val(val->i, &str_cal); + } else if (retval >= 0) { + cal_table_t str_cal = K3_SMH_CAL; + + retval = kenwood_safe_transaction(rig, "SMH", lvlbuf, 10, 7); + if (retval != RIG_OK) + return retval; + + sscanf(lvlbuf+3, "%d", &val->i); /* rawstr */ + + val->i = (int) rig_raw2val(val->i, &str_cal); + } else { + rig_debug(RIG_DEBUG_ERR, "%s: Firmware version comparison failed!\n", + __func__); + return -RIG_EINVAL; + } + + break; + + default: + retval = kenwood_get_level(rig, vfo, level, val); + if (retval != RIG_OK) + return retval; + break; + } + + return RIG_OK; +} + + + /* Private K3 helper functions */ diff --git a/src/iofunc.c b/src/iofunc.c index 283739f68..4aebca78e 100644 --- a/src/iofunc.c +++ b/src/iofunc.c @@ -460,7 +460,7 @@ int HAMLIB_API read_string(hamlib_port_t *p, char *rxbuffer, size_t rxmax, const int stopset_len) { fd_set rfds, efds; - struct timeval tv, tv_timeout; + struct timeval tv, tv_timeout, start_time, end_time, elapsed_time; int rd_count, total_count = 0; int retval; @@ -470,6 +470,9 @@ int HAMLIB_API read_string(hamlib_port_t *p, char *rxbuffer, size_t rxmax, const tv_timeout.tv_sec = p->timeout/1000; tv_timeout.tv_usec = (p->timeout%1000)*1000; + /* Store the time of the read loop start */ + gettimeofday(&start_time, NULL); + while (total_count < rxmax-1) { tv = tv_timeout; /* select may have updated it */ @@ -515,8 +518,12 @@ int HAMLIB_API read_string(hamlib_port_t *p, char *rxbuffer, size_t rxmax, const rxbuffer[total_count] = '\000'; if (total_count == 0) { - rig_debug(RIG_DEBUG_WARN, "%s: timedout without reading a character\n", - __FUNCTION__); + /* Record timeout time and caculate elapsed time */ + gettimeofday(&end_time, NULL); + timersub(&end_time, &start_time, &elapsed_time); + + rig_debug(RIG_DEBUG_WARN, "%s: timedout %d.%d seconds without reading a character.\n", + __FUNCTION__, elapsed_time.tv_sec, elapsed_time.tv_usec); return -RIG_ETIMEOUT; }