Moved K3 specific functions to k3.c

Keep shared functions in elecraft.c



git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@3004 7ae35d74-ebe9-4afe-98af-79ac388436b8
Hamlib-1.2.13
Nate Bargmann, N0NB 2010-11-03 03:08:33 +00:00
rodzic a298c8e7eb
commit 8ac3a90885
6 zmienionych plików z 249 dodań i 185 usunięć

23
kenwood/README.k2 100644
Wyświetl plik

@ -0,0 +1,23 @@
Elecraft K2 notes and Hamlib errata by Nate Bargmann, N0NB.
The K2 shares some backend code with the K3. This code can be found in
elecraft.[c|h] while any K2 specific is found in k2.c
As always, comments and bug reports should be submitted to
hamlib-developer@lists.sourceforge.net
elecraft_open()
===============
The kenwood_open() function fails for the Elecraft radios as the function checks
the backend to be certain the ID from the radio matches the backend that called
the function. As the ID command of the Elecraft radios returns "017" which
corresponds to the TS-570, the backend test fails. Rather than muck up a
working function, I chose to implement an independent elecraft_open which not
only checks for the existence of a connected radio that returns an ID of "017",
it also checks for K2 or K3 extensions and sets a pair of private variables
that may be used later for advanced functions. This way the backend should be
able to reliably test for either a K2 or K3 (needs more testing with the K2).

Wyświetl plik

@ -3,8 +3,25 @@ Elecraft K3 notes and Hamlib errata by Nate Bargmann, N0NB.
While the K3 uses a large set of commands compatible with the standard Kenwood
commands, a number are extended and others have side effects that are peculiar
to the K3. As such, a separate set of elecraft.[c|h] files have been written
to support the K3 in the best possible way. As always, comments and bug reports
should be submitted to hamlib-developer@lists.sourceforge.net
to support the K2 and K3 in the best possible way using shared code when
possible. K3 specific code can be found in k3.c
As always, comments and bug reports should be submitted to
hamlib-developer@lists.sourceforge.net
elecraft_open()
===============
The kenwood_open() function fails for the Elecraft radios as the function checks
the backend to be certain the ID from the radio matches the backend that called
the function. As the ID command of the Elecraft radios returns "017" which
corresponds to the TS-570, the backend test fails. Rather than muck up a
working function, I chose to implement an independent elecraft_open which not
only checks for the existence of a connected radio that returns an ID of "017",
it also checks for K2 or K3 extensions and sets a pair of private variables
that may be used later for advanced functions. This way the backend should be
able to reliably test for either a K2 or K3 (needs more testing with the K2).
k3_set_vfo()

Wyświetl plik

@ -28,7 +28,7 @@
/* Actual read extension levels from radio.
*
* Values stored in these variables maps to elecraft_ext_id_string_list.level
* Values stored in these variables map to elecraft_ext_id_string_list.level
* and are only written to by the elecraft_get_extension_level() private
* function during elecraft_open() and thereafter shall be treated as
* READ ONLY!
@ -97,173 +97,6 @@ int elecraft_open(RIG *rig)
}
/* k3_get_mode()
*
* The K3 supports a new command, DT, to query the data submode so
* RIG_MODE_PKTUSB and RIG_MODE_PKTLSB can be supported.
*/
int k3_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!rig || !mode || !width)
return -RIG_EINVAL;
char buf[KENWOOD_MAX_BUF_LEN];
int err;
rmode_t temp_m;
pbwidth_t temp_w;
err = kenwood_get_mode(rig, vfo, &temp_m, &temp_w);
if (err != RIG_OK)
return err;
if (temp_m == RIG_MODE_RTTY) {
err = kenwood_safe_transaction(rig, "DT", buf, KENWOOD_MAX_BUF_LEN, 4);
if (err != RIG_OK) {
rig_debug(RIG_DEBUG_ERR, "%s: Cannot read K3 DT value\n", __func__);
return err;
}
switch(atoi(&buf[2])) {
case K3_MODE_DATA_A:
*mode = RIG_MODE_PKTUSB;
break;
case K3_MODE_AFSK_A:
*mode = RIG_MODE_RTTY;
break;
default:
rig_debug(RIG_DEBUG_ERR, "%s: unsupported data sub-mode %c\n", __func__, buf[2]);
return -RIG_EINVAL;
}
} else if (temp_m == RIG_MODE_RTTYR) {
err = kenwood_safe_transaction(rig, "DT", buf, KENWOOD_MAX_BUF_LEN, 4);
if (err != RIG_OK) {
rig_debug(RIG_DEBUG_ERR, "%s: Cannot read K3 DT value\n", __func__);
return err;
}
switch(atoi(&buf[2])) {
case K3_MODE_DATA_A:
*mode = RIG_MODE_PKTLSB;
break;
case K3_MODE_AFSK_A:
*mode = RIG_MODE_RTTYR;
break;
default:
rig_debug(RIG_DEBUG_ERR, "%s: unsupported data sub-mode %c\n", __func__, buf[2]);
return -RIG_EINVAL;
}
} else
*mode = temp_m;
/* The K3 is not limited to specific filter widths so we can query
* the actual bandwidth using the BW command
*/
err = kenwood_safe_transaction(rig, "BW", buf, KENWOOD_MAX_BUF_LEN, 7);
if (err != RIG_OK) {
rig_debug(RIG_DEBUG_ERR, "%s: Cannot read K3 BW value\n", __func__);
return err;
}
*width = atoi(&buf[2]) * 10;
return RIG_OK;
}
/* k3_set_mode()
*
* As with k3_get_mode(), the K3 can also set the data submodes which allows
* use of RIG_MODE_PKTUSB and RIG_MODE_PKLSB.
*/
int k3_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!rig)
return -RIG_EINVAL;
int err;
char cmd_s[16];
switch (mode) {
case RIG_MODE_PKTLSB:
mode = RIG_MODE_RTTYR;
strncpy(cmd_s, "DT0", 5);
break;
case RIG_MODE_PKTUSB:
mode = RIG_MODE_RTTY;
strncpy(cmd_s, "DT0", 5);
break;
case RIG_MODE_RTTY:
case RIG_MODE_RTTYR:
strncpy(cmd_s, "DT1", 5);
break;
default:
break;
}
/* kenwood_set_mode() ignores width value for K2/K3/TS-570 */
err = kenwood_set_mode(rig, vfo, mode, width);
if (err != RIG_OK)
return err;
/* Now set data sub-mode. K3 needs to be in a DATA mode before setting
* the sub-mode.
*/
if (mode == RIG_MODE_PKTLSB || mode == RIG_MODE_PKTUSB
|| mode == RIG_MODE_RTTY || mode == RIG_MODE_RTTYR) {
err = kenwood_simple_cmd(rig, cmd_s);
if (err != RIG_OK)
return err;
}
/* and set the requested bandwidth. On my K3, the bandwidth is rounded
* down to the nearest 50 Hz, i.e. sending BW0239; will cause the bandwidth
* to be set to 2.350 kHz. As the width must be divided by 10, 10 Hz values
* between 0 and 4 round down to the nearest 100 Hz and values between 5
* and 9 round down to the nearest 50 Hz.
*
* width string value must be padded with leading '0' to equal four
* characters.
*/
sprintf(cmd_s, "BW%04d", width / 10);
err = kenwood_simple_cmd(rig, cmd_s);
if (err != RIG_OK)
return err;
return RIG_OK;
}
/* The K3 changes "VFOs" by swapping the contents of
* the upper display with the lower display. This function
* accomplishes this by sending the emulation command, SWT11;
* to the K3 to emulate a tap of the A/B button.
*/
int k3_set_vfo(RIG *rig, vfo_t vfo)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!rig)
return -RIG_EINVAL;
int err;
switch (vfo) {
case RIG_VFO_B:
err = kenwood_simple_cmd(rig, "SWT11");
if (err != RIG_OK)
return err;
break;
default:
break;
}
return RIG_OK;
}
/* Private helper functions */

Wyświetl plik

@ -42,7 +42,7 @@ struct elecraft_ext_id_string {
const char *id;
};
/* Data sub-modes are provide from the K3 via the DT command */
/* Data sub-modes are provided from the K3 via the DT command */
enum k3_data_submodes_e {
K3_MODE_DATA_A = 0, /* DT0; */
K3_MODE_AFSK_A, /* DT1; */
@ -53,8 +53,5 @@ enum k3_data_submodes_e {
/* Elecraft extension function declarations */
int elecraft_open(RIG *rig);
int k3_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width);
int k3_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width);
int k3_set_vfo(RIG *rig, vfo_t vfo);
#endif /* _ELECRAFT_H */

Wyświetl plik

@ -47,6 +47,17 @@ static struct kenwood_priv_caps k2_priv_caps = {
.cmdtrm = EOM_KEN,
};
/* Actual read extension levels from radio.
*
* The Value stored in this variable maps to elecraft_ext_id_string_list.level
* and is only written to by the elecraft_get_extension_level() private
* function during elecraft_open() and thereafter shall be treated as
* READ ONLY!
*/
extern int k2_ext_lvl; /* Initial K2 extension level */
/*
* KIO2 rig capabilities.
* This kit can recognize a large subset of TS-570 commands.

Wyświetl plik

@ -1,20 +1,21 @@
/*
* Hamlib Kenwood backend - Elecraft K3 description
* Copyright (c) 2002-2009 by Stephane Fillod
* Copyright (C) 2010 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 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 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 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* 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 Library General Public License for more details.
* 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 Library General Public
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
@ -50,11 +51,27 @@ static struct kenwood_priv_caps k3_priv_caps = {
};
/* Actual read extension levels from radio.
*
* The Value stored in this variable maps to elecraft_ext_id_string_list.level
* and is only written to by the elecraft_get_extension_level() private
* function during elecraft_open() and thereafter shall be treated as
* READ ONLY!
*/
extern int k3_ext_lvl; /* Initial K3 extension level */
/* K3 specific function declarations */
int k3_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width);
int k3_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width);
int k3_set_vfo(RIG *rig, vfo_t vfo);
/*
* KIO3 rig capabilities.
* This kit can recognize a large subset of TS-570/K2 commands and has many
* extensions of its own. Extension backend functions to standard Kenwood
* command are defined in elecraft.c (shared with K2).
* command are defined in elecraft.c (shared with K2) and in this file.
*
* Part of info comes from http://www.elecraft.com/K2_Manual_Download_Page.htm#K3
* look for K3 Programmer's Reference PDF
@ -190,6 +207,172 @@ const struct rig_caps k3_caps = {
/*
* K3 extension function definitions in elecraft.c
* K3 extension function definitions follow
*/
/* k3_get_mode()
*
* The K3 supports a new command, DT, to query the data submode so
* RIG_MODE_PKTUSB and RIG_MODE_PKTLSB can be supported.
*/
int k3_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!rig || !mode || !width)
return -RIG_EINVAL;
char buf[KENWOOD_MAX_BUF_LEN];
int err;
rmode_t temp_m;
pbwidth_t temp_w;
err = kenwood_get_mode(rig, vfo, &temp_m, &temp_w);
if (err != RIG_OK)
return err;
if (temp_m == RIG_MODE_RTTY) {
err = kenwood_safe_transaction(rig, "DT", buf, KENWOOD_MAX_BUF_LEN, 4);
if (err != RIG_OK) {
rig_debug(RIG_DEBUG_ERR, "%s: Cannot read K3 DT value\n", __func__);
return err;
}
switch(atoi(&buf[2])) {
case K3_MODE_DATA_A:
*mode = RIG_MODE_PKTUSB;
break;
case K3_MODE_AFSK_A:
*mode = RIG_MODE_RTTY;
break;
default:
rig_debug(RIG_DEBUG_ERR, "%s: unsupported data sub-mode %c\n", __func__, buf[2]);
return -RIG_EINVAL;
}
} else if (temp_m == RIG_MODE_RTTYR) {
err = kenwood_safe_transaction(rig, "DT", buf, KENWOOD_MAX_BUF_LEN, 4);
if (err != RIG_OK) {
rig_debug(RIG_DEBUG_ERR, "%s: Cannot read K3 DT value\n", __func__);
return err;
}
switch(atoi(&buf[2])) {
case K3_MODE_DATA_A:
*mode = RIG_MODE_PKTLSB;
break;
case K3_MODE_AFSK_A:
*mode = RIG_MODE_RTTYR;
break;
default:
rig_debug(RIG_DEBUG_ERR, "%s: unsupported data sub-mode %c\n", __func__, buf[2]);
return -RIG_EINVAL;
}
} else
*mode = temp_m;
/* The K3 is not limited to specific filter widths so we can query
* the actual bandwidth using the BW command
*/
err = kenwood_safe_transaction(rig, "BW", buf, KENWOOD_MAX_BUF_LEN, 7);
if (err != RIG_OK) {
rig_debug(RIG_DEBUG_ERR, "%s: Cannot read K3 BW value\n", __func__);
return err;
}
*width = atoi(&buf[2]) * 10;
return RIG_OK;
}
/* k3_set_mode()
*
* As with k3_get_mode(), the K3 can also set the data submodes which allows
* use of RIG_MODE_PKTUSB and RIG_MODE_PKLSB.
*/
int k3_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!rig)
return -RIG_EINVAL;
int err;
char cmd_s[16];
switch (mode) {
case RIG_MODE_PKTLSB:
mode = RIG_MODE_RTTYR;
strncpy(cmd_s, "DT0", 5);
break;
case RIG_MODE_PKTUSB:
mode = RIG_MODE_RTTY;
strncpy(cmd_s, "DT0", 5);
break;
case RIG_MODE_RTTY:
case RIG_MODE_RTTYR:
strncpy(cmd_s, "DT1", 5);
break;
default:
break;
}
/* kenwood_set_mode() ignores width value for K2/K3/TS-570 */
err = kenwood_set_mode(rig, vfo, mode, width);
if (err != RIG_OK)
return err;
/* Now set data sub-mode. K3 needs to be in a DATA mode before setting
* the sub-mode.
*/
if (mode == RIG_MODE_PKTLSB || mode == RIG_MODE_PKTUSB
|| mode == RIG_MODE_RTTY || mode == RIG_MODE_RTTYR) {
err = kenwood_simple_cmd(rig, cmd_s);
if (err != RIG_OK)
return err;
}
/* and set the requested bandwidth. On my K3, the bandwidth is rounded
* down to the nearest 50 Hz, i.e. sending BW0239; will cause the bandwidth
* to be set to 2.350 kHz. As the width must be divided by 10, 10 Hz values
* between 0 and 4 round down to the nearest 100 Hz and values between 5
* and 9 round down to the nearest 50 Hz.
*
* width string value must be padded with leading '0' to equal four
* characters.
*/
sprintf(cmd_s, "BW%04d", width / 10);
err = kenwood_simple_cmd(rig, cmd_s);
if (err != RIG_OK)
return err;
return RIG_OK;
}
/* The K3 changes "VFOs" by swapping the contents of
* the upper display with the lower display. This function
* accomplishes this by sending the emulation command, SWT11;
* to the K3 to emulate a tap of the A/B button.
*/
int k3_set_vfo(RIG *rig, vfo_t vfo)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!rig)
return -RIG_EINVAL;
int err;
switch (vfo) {
case RIG_VFO_B:
err = kenwood_simple_cmd(rig, "SWT11");
if (err != RIG_OK)
return err;
break;
default:
break;
}
return RIG_OK;
}