From a69f977c426fd41bec879ca196b803b8f703555c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Fillod=2C=20F8CFE?= Date: Wed, 2 Jan 2002 23:41:44 +0000 Subject: [PATCH] fixes from Francois to make the TH-D7 to work git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@835 7ae35d74-ebe9-4afe-98af-79ac388436b8 --- kenwood/th.c | 57 ++++++---- kenwood/thd7.c | 274 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 304 insertions(+), 27 deletions(-) diff --git a/kenwood/th.c b/kenwood/th.c index 4f315af18..f16afbfa5 100644 --- a/kenwood/th.c +++ b/kenwood/th.c @@ -2,7 +2,7 @@ * Hamlib Kenwood backend - TH handheld primitives * Copyright (c) 2001 by Stephane Fillod * - * $Id: th.c,v 1.2 2001-12-20 22:59:08 fillods Exp $ + * $Id: th.c,v 1.3 2002-01-02 23:41:44 fillods Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -62,7 +62,7 @@ int th_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); int th_set_vfo(RIG *rig, vfo_t vfo) { unsigned char ackbuf[24]; - int ack_len, retval; + int retval, ack_len = 0; /* * FIXME: vfo==RIG_VFO_CURR @@ -93,12 +93,21 @@ int th_set_vfo(RIG *rig, vfo_t vfo) int th_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char freqbuf[24], ackbuf[24]; - int freq_len, ack_len, retval; + int retval, freq_len, ack_len = 0; + memset(ackbuf, 0, sizeof(ackbuf)); /* for alpha debugging only */ freq_len = sprintf(freqbuf,"FQ %011Ld,0" EOM, freq); - retval = kenwood_transaction (rig, freqbuf, freq_len, ackbuf, &ack_len); + rig_debug(RIG_DEBUG_TRACE, "Ack msg: (%i) %s\n", ack_len, ackbuf); /* for alpha debugging only */ + + /* FIXME: ack_len returns with zero even when many data is read. + * (something wrong with kenwook_transaction) 2001-12-30 fgr. + */ + if ((ackbuf[0] == 'N') && (ackbuf[1] == '\n')) { + return -RIG_ERJCTED; + } + return retval; } @@ -109,7 +118,8 @@ int th_set_freq(RIG *rig, vfo_t vfo, freq_t freq) int th_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { unsigned char freqbuf[24]; - int freq_len, retval; + int retval, freq_len = 0; + rig_debug(RIG_DEBUG_TRACE, __FUNCTION__" called\n"); retval = kenwood_transaction (rig, "FQ" EOM, 3, freqbuf, &freq_len); if (retval != RIG_OK) @@ -127,7 +137,7 @@ int th_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) int th_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char mdbuf[24],ackbuf[24]; - int mdbuf_len, ack_len, kmode, retval; + int retval, kmode, mdbuf_len, ack_len = 0; switch (mode) { case RIG_MODE_FM: kmode = MD_FM; break; @@ -154,17 +164,23 @@ int th_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) */ int th_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { - int ack_len, retval; + int retval, ack_len = 0; unsigned char ackbuf[24]; retval = kenwood_transaction (rig, "MD" EOM, 3, ackbuf, &ack_len); if (retval != RIG_OK) return retval; - if (ack_len != 5) { - rig_debug(RIG_DEBUG_ERR,"th_get_mode: ack NG, len=%d\n", - ack_len); - return -RIG_ERJCTED; +// if (ack_len != 5) { /* ack_len does not work. */ + if (ackbuf[0] == 'N' && ackbuf[1] == '\n') { + rig_debug(RIG_DEBUG_ERR,"th_get_mode: ack NG, len=%d\n",ack_len); + return -RIG_ERJCTED; + } + + if (ackbuf[0] != 'M' || ackbuf[1] != 'D' || ackbuf[2] != ' ') { + rig_debug(RIG_DEBUG_ERR, __FUNCTION__": unknown replay (%i) %s\n", + ack_len, ackbuf); + return -RIG_ERJCTED; } *width = RIG_PASSBAND_NORMAL; /* FIXME */ @@ -177,7 +193,7 @@ int th_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) case MD_CW: *mode = RIG_MODE_CW; break; default: rig_debug(RIG_DEBUG_ERR,"th_get_mode: " - "unsupported mode %d\n", ackbuf[3]); + "unsupported mode '%c'\n", ackbuf[3]); return -RIG_EINVAL; } @@ -195,7 +211,7 @@ int th_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { const struct rig_caps *caps; unsigned char tonebuf[24], ackbuf[24]; - int tone_len, ack_len; + int tone_len, ack_len = 0; int i; caps = rig->caps; @@ -222,18 +238,21 @@ int th_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { const struct rig_caps *caps; unsigned char tonebuf[24]; - int tone_len, i, retval; + int i, retval, tone_len = 0; unsigned int tone_idx; - + + memset(tonebuf, 0, sizeof(tonebuf)); /* for terminating zero of string */ + caps = rig->caps; /* TODO: replace menu no 57 by a define */ - + retval = kenwood_transaction (rig, "TN" EOM, 3, tonebuf, &tone_len); if (retval != RIG_OK) return retval; - if (tone_len != 10) { + //if (tone_len != 10) { + if (tonebuf[0] != 'T' || tonebuf[1] != 'N') { rig_debug(RIG_DEBUG_ERR,"th_get_ctcss_tone: unexpected reply " "'%s', len=%d\n", tonebuf, tone_len); return -RIG_ERJCTED; @@ -246,9 +265,9 @@ int th_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) "no (%04d)\n", tone_idx); return -RIG_EPROTO; } - + /* check this tone exists. That's better than nothing. */ - for (i = 0; ictcss_list[i] == 0) { rig_debug(RIG_DEBUG_ERR,"th_get_ctcss_tone: CTCSS NG " "(%04d)\n", tone_idx); diff --git a/kenwood/thd7.c b/kenwood/thd7.c index 326d1f41f..8323b6277 100644 --- a/kenwood/thd7.c +++ b/kenwood/thd7.c @@ -2,7 +2,7 @@ * Hamlib Kenwood backend - TH-D7 description * Copyright (c) 2000,2001 by Stephane Fillod * - * $Id: thd7.c,v 1.3 2001-12-16 11:17:42 fillods Exp $ + * $Id: thd7.c,v 1.4 2002-01-02 23:41:44 fillods Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -38,8 +38,21 @@ #include "kenwood.h" #include "th.h" +#if 1 +#define RIG_ASSERT(x) if (!(x)) { rig_debug(RIG_DEBUG_ERR, "Assertion failed on line %i\n",__LINE__); abort(); } +#else +#define RIG_ASSERT(x) +#endif -#define THD7_MODES (RIG_MODE_FM|RIG_MODE_AM) + +static int thd7_set_vfo(RIG *rig, vfo_t vfo); +static int thd7_get_vfo(RIG *rig, vfo_t *vfo); +static int thd7_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); +static int thd7_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); +static int thd7_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); +static int thd7_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); + +#define THD7_MODES (RIG_MODE_FM|RIG_MODE_AM) #define THD7_MODES_TX (RIG_MODE_FM) #define THD7_FUNC_ALL (RIG_FUNC_TSQL|RIG_FUNC_AIP|RIG_FUNC_SQL) @@ -62,7 +75,7 @@ model_name:"TH-D7A", mfg_name: "Kenwood", version: "0.1", copyright: "LGPL", -status: RIG_STATUS_UNTESTED, +status: RIG_STATUS_ALPHA, rig_type: RIG_TYPE_HANDHELD|RIG_FLAG_APRS|RIG_FLAG_TNC|RIG_FLAG_DXCLUSTER, ptt_type: RIG_PTT_RIG, dcd_type: RIG_DCD_RIG, @@ -139,16 +152,261 @@ priv: NULL, set_freq: th_set_freq, get_freq: th_get_freq, -set_mode: th_set_mode, -get_mode: th_get_mode, -set_vfo: th_set_vfo, -set_ctcss_tone: th_set_ctcss_tone, -get_ctcss_tone: th_get_ctcss_tone, +set_mode: thd7_set_mode, +get_mode: thd7_get_mode, +set_vfo: thd7_set_vfo, +get_vfo: thd7_get_vfo, +set_ctcss_tone: thd7_set_ctcss_tone, +get_ctcss_tone: thd7_get_ctcss_tone, + +/* Untested and will most probably not work! * set_ptt: kenwood_set_ptt, get_dcd: kenwood_get_dcd, vfo_op: kenwood_vfo_op, set_mem: kenwood_set_mem, get_mem: kenwood_get_mem, + */ }; +#define EOM "\r" + + +/* + * thd7_set_vfo + * Assumes rig!=NULL + */ +static int +thd7_set_vfo(RIG *rig, vfo_t vfo) +{ + unsigned char vsel, vfobuf[16], ackbuf[24]; + int retval, vfo_len, ack_len = 0; + + rig_debug(RIG_DEBUG_TRACE, __FUNCTION__" called\n"); + RIG_ASSERT(rig != NULL); + + switch (vfo) { + case RIG_VFO_A: vsel = '0'; break; + case RIG_VFO_B: vsel = '1'; break; + default: + rig_debug(RIG_DEBUG_ERR, __FUNCTION__": unsupported VFO %d\n", vfo); + return -RIG_EINVAL; + } + + vfo_len = sprintf(vfobuf, "BC %c" EOM, vsel); + retval = kenwood_transaction (rig, vfobuf, vfo_len, ackbuf, &ack_len); + if (retval != RIG_OK) + return retval; + + if (ackbuf[0] == 'N' && ackbuf[1] == '\n') { + return -RIG_ERJCTED; + } + return RIG_OK; +} + +/* + * thd7_get_vfo + * Assumes rig!=NULL + */ +static int +thd7_get_vfo(RIG *rig, vfo_t *vfo) +{ + unsigned char ackbuf[16]; + int retval, ack_len = 0; + + rig_debug(RIG_DEBUG_TRACE, __FUNCTION__" called\n"); + RIG_ASSERT(rig != NULL); + + retval = kenwood_transaction (rig, "BC" EOM, 3, ackbuf, &ack_len); + if (retval != RIG_OK) + return retval; + +// if (ack_len != 5) { /* for some reason ack_len is zero */ + if (ackbuf[0] != 'B' || ackbuf[1] != 'C' || ackbuf[2] != ' ') { + rig_debug(RIG_DEBUG_ERR, __FUNCTION__": unexpected reply " + "'%s', len=%d\n", ackbuf, ack_len); + return -RIG_ERJCTED; + } + + switch (ackbuf[3]) { + case '0': *vfo = RIG_VFO_A; break; + case '1': *vfo = RIG_VFO_B; break; + default: + rig_debug(RIG_DEBUG_ERR, __FUNCTION__": unexpected VFO value %c\n", + ackbuf[3]); + return -RIG_ERJCTED; + } + + return RIG_OK; +} + +/* + * thd7_set_mode + * Assumes rig!=NULL + */ +static int +thd7_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) +{ + unsigned char mdbuf[24], ackbuf[24]; + int retval, kmode, mdbuf_len, ack_len = 0; + + rig_debug(RIG_DEBUG_TRACE, __FUNCTION__" called\n"); + RIG_ASSERT(rig != NULL); + + switch (mode) { + case RIG_MODE_FM: kmode = '0'; break; + case RIG_MODE_AM: kmode = '1'; break; + default: + rig_debug(RIG_DEBUG_ERR,__FUNCTION__": unsupported mode %d\n", mode); + return -RIG_EINVAL; + } + mdbuf_len = sprintf(mdbuf, "MD %c" EOM, kmode); + retval = kenwood_transaction (rig, mdbuf, mdbuf_len, ackbuf, &ack_len); + if (retval != RIG_OK) + return retval; + + if (ackbuf[0] == 'N' && ackbuf[1] == '\n') { + rig_debug(RIG_DEBUG_ERR, __FUNCTION__": ack NG, len=%d\n", ack_len); + return -RIG_ERJCTED; + } + + return retval; +} + +/* + * thd7_get_mode + * Assumes rig!=NULL, mode!=NULL + */ +static int +thd7_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) +{ + int retval, ack_len = 0; + unsigned char ackbuf[24]; + + rig_debug(RIG_DEBUG_TRACE, __FUNCTION__": called\n"); + RIG_ASSERT(rig != NULL); + RIG_ASSERT(mode != NULL); + memset(ackbuf, 0, sizeof(ackbuf)); /* for terminating zero of string */ + + retval = kenwood_transaction (rig, "MD" EOM, 3, ackbuf, &ack_len); + if (retval != RIG_OK) + return retval; + + /*if (ack_len != 5) { */ /* ack_len does not work. */ + if (ackbuf[0] == 'N' && ackbuf[1] == '\n') { + rig_debug(RIG_DEBUG_ERR, __FUNCTION__": ack NG, len=%d\n", ack_len); + return -RIG_ERJCTED; + } + + if (ackbuf[0] != 'M' || ackbuf[1] != 'D' || ackbuf[2] != ' ') { + rig_debug(RIG_DEBUG_ERR, __FUNCTION__": unknown replay (%i) %s\n", + ack_len, ackbuf); + return -RIG_ERJCTED; + } + + if (width) + *width = RIG_PASSBAND_NORMAL; + + switch (ackbuf[3]) { + case '0': *mode = RIG_MODE_FM; break; + case '1': *mode = RIG_MODE_AM; break; + default: + rig_debug(RIG_DEBUG_ERR, __FUNCTION__": unsupported mode %c\n", ackbuf[3]); + return -RIG_EINVAL; + } + return RIG_OK; +} + +#ifndef RIG_TONEMAX +#define RIG_TONEMAX 38 +#endif + +/* + * thd7_set_ctcss_tone + * Assumes rig!=NULL, rig->caps->ctcss_list != NULL + */ +static int +thd7_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) +{ + const struct rig_caps *caps; + unsigned char tonebuf[24], ackbuf[24]; + int retval, tone_len, ack_len = 0; + int i; + + rig_debug(RIG_DEBUG_TRACE, __FUNCTION__": called\n"); + RIG_ASSERT(rig != NULL); + RIG_ASSERT(rig->caps != NULL && rig->caps->ctcss_list != NULL); + memset(ackbuf, 0, sizeof(ackbuf)); + + caps = rig->caps; + + for (i = 0; caps->ctcss_list[i] != 0 && i < RIG_TONEMAX; i++) { + if (caps->ctcss_list[i] == tone) + break; + } + if (caps->ctcss_list[i] != tone) + return -RIG_EINVAL; + + i += (i == 0) ? 1 : 2; /* Correct for TH-7D anomally */ + tone_len = sprintf(tonebuf, "CTN %02d" EOM, i); + retval = kenwood_transaction (rig, tonebuf, tone_len, ackbuf, &ack_len); + if (retval != RIG_OK) + return retval; + + /* error/result checking */ + if (ackbuf[0] == 'N' && ackbuf[1] == '\n') { + rig_debug(RIG_DEBUG_ERR, __FUNCTION__": negative acknowledgment\n"); + return -RIG_ERJCTED; + } + if (ackbuf[0] != 'C' || ackbuf[1] != 'T' || ackbuf[2] != 'N') { + rig_debug(RIG_DEBUG_ERR, __FUNCTION__": unexpected reply " + "'%s', len=%d\n", tonebuf, tone_len); + return -RIG_ERJCTED; + } + return RIG_OK; +} + +/* + * thd7_get_ctcss_tone + * Assumes rig!=NULL, rig->caps!=NULL + */ +static int +thd7_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) +{ + const struct rig_caps *caps; + unsigned char tonebuf[24]; + int retval, tone_len = 0; + unsigned int tone_idx; + + rig_debug(RIG_DEBUG_TRACE, __FUNCTION__": called\n"); + RIG_ASSERT(rig != NULL); + RIG_ASSERT(rig->caps != NULL && rig->caps->ctcss_list != NULL); + memset(tonebuf, 0, sizeof(tonebuf)); /* for terminating zero of string */ + + caps = rig->caps; + + retval = kenwood_transaction (rig, "CTN" EOM, 4, tonebuf, &tone_len); + if (retval != RIG_OK) + return retval; + + if (tonebuf[0] != 'C' || tonebuf[1] != 'T' || tonebuf[2] != 'N') { + rig_debug(RIG_DEBUG_ERR, __FUNCTION__": unexpected reply " + "'%s', len=%d\n", tonebuf, tone_len); + return -RIG_ERJCTED; + } + + sscanf(tonebuf+3, "%u", (int*)&tone_idx); + + /* verify tone index for TH-7D rig */ + if (tone_idx <= 0 || tone_idx == 2 || tone_idx > 39) { + rig_debug(RIG_DEBUG_ERR, __FUNCTION__ + ": Unexpected CTCSS no (%04d)\n", tone_idx); + return -RIG_EPROTO; + } + tone_idx -= (tone_idx == 1) ? 1 : 2; /* Correct for TH-7D anomaly */ + *tone = caps->ctcss_list[tone_idx]; + return RIG_OK; +} + + +