diff --git a/icom/ic706.c b/icom/ic706.c index 22c2d281b..2def75b99 100644 --- a/icom/ic706.c +++ b/icom/ic706.c @@ -7,7 +7,7 @@ * using the "CI-V" interface. * * - * $Id: ic706.c,v 1.22 2001-06-03 19:54:05 f4cfe Exp $ + * $Id: ic706.c,v 1.23 2001-06-26 20:55:29 f4cfe Exp $ * * * @@ -57,7 +57,8 @@ #define IC706_VFO_ALL (RIG_VFO_A|RIG_VFO_B) -#define IC706_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) +#define IC706_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) +#define IC706_SCAN_OPS (RIG_SCAN_MEM) #define IC706IIG_STR_CAL { 16, \ { \ @@ -368,7 +369,8 @@ max_rit: Hz(0), max_xit: Hz(0), max_ifshift: Hz(0), targetable_vfo: 0, -vfo_ops: IC706_OPS, +vfo_ops: IC706_VFO_OPS, +scan_ops: IC706_SCAN_OPS, transceive: RIG_TRN_RIG, bank_qty: 0, chan_desc_sz: 0, @@ -461,6 +463,7 @@ mv_ctl: icom_mv_ctl, #else vfo_op: icom_vfo_op, #endif +scan: icom_scan, set_ptt: icom_set_ptt, get_ptt: icom_get_ptt, get_dcd: icom_get_dcd, diff --git a/icom/icom.c b/icom/icom.c index 39018928b..8aab76c4b 100644 --- a/icom/icom.c +++ b/icom/icom.c @@ -6,7 +6,7 @@ * via serial interface to an ICOM using the "CI-V" interface. * * - * $Id: icom.c,v 1.31 2001-06-20 06:08:21 f4cfe Exp $ + * $Id: icom.c,v 1.32 2001-06-26 20:55:28 f4cfe Exp $ * * * @@ -435,7 +435,6 @@ int icom_set_vfo(RIG *rig, vfo_t vfo) switch(vfo) { case RIG_VFO_A: icvfo = S_VFOA; break; case RIG_VFO_B: icvfo = S_VFOB; break; -#ifdef RIG_VFO_VFO case RIG_VFO_VFO: retval = icom_transaction (rig, C_SET_VFO, -1, NULL, 0, ackbuf, &ack_len); @@ -447,8 +446,6 @@ int icom_set_vfo(RIG *rig, vfo_t vfo) return -RIG_ERJCTED; } return RIG_OK; -#endif -#ifdef RIG_VFO_MEM case RIG_VFO_MEM: retval = icom_transaction (rig, C_SET_MEM, -1, NULL, 0, ackbuf, &ack_len); @@ -460,7 +457,6 @@ int icom_set_vfo(RIG *rig, vfo_t vfo) return -RIG_ERJCTED; } return RIG_OK; -#endif default: rig_debug(RIG_DEBUG_ERR,"icom: Unsupported VFO %d\n", vfo); @@ -2059,6 +2055,75 @@ int icom_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) } #endif +/* + * icom_scan, scan operation + * Assumes rig!=NULL, rig->state.priv!=NULL + */ +int icom_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) +{ + struct icom_priv_data *priv; + struct rig_state *rs; + unsigned char scanbuf[16]; + unsigned char ackbuf[16]; + int scan_len, ack_len, retval; + int scan_cn, scan_sc; + + rs = &rig->state; + priv = (struct icom_priv_data*)rs->priv; + + scan_len = 0; + scan_cn = C_CTL_SCAN; + + switch(scan) { + case RIG_SCAN_STOP: + scan_sc = S_SCAN_STOP; + break; + case RIG_SCAN_MEM: + retval = icom_set_vfo(rig, RIG_VFO_MEM); + if (retval != RIG_OK) + return retval; + scan_sc = S_SCAN_START; + break; + case RIG_SCAN_SLCT: + retval = icom_set_vfo(rig, RIG_VFO_MEM); + if (retval != RIG_OK) + return retval; + scan_sc = S_SCAN_START; + break; + case RIG_SCAN_PRIO: + case RIG_SCAN_PROG: + /* TODO: for SCAN_PROG, check this is an edge chan */ + /* BTW, I'm wondering if this is possible with CI-V */ + retval = icom_set_mem(rig, RIG_VFO_CURR, ch); + if (retval != RIG_OK) + return retval; + retval = icom_set_vfo(rig, RIG_VFO_VFO); + if (retval != RIG_OK) + return retval; + scan_sc = S_SCAN_START; + break; + case RIG_SCAN_DELTA: + scan_sc = S_SCAN_DELTA; /* TODO: delta-f support */ + break; + default: + rig_debug(RIG_DEBUG_ERR,"Unsupported scan %#x", scan); + return -RIG_EINVAL; + } + + retval = icom_transaction (rig, scan_cn, scan_sc, scanbuf, scan_len, + ackbuf, &ack_len); + if (retval != RIG_OK) + return retval; + + if (ack_len != 1 || ackbuf[0] != ACK) { + rig_debug(RIG_DEBUG_ERR,"icom_scan: ack NG (%#.2x), " + "len=%d\n", ackbuf[0], ack_len); + return -RIG_ERJCTED; + } + + return RIG_OK; +} + /* * icom_decode is called by sa_sigio, when some asynchronous * data has been received from the rig diff --git a/icom/icom.h b/icom/icom.h index 53541ec0c..54c0218d2 100644 --- a/icom/icom.h +++ b/icom/icom.h @@ -6,7 +6,7 @@ * via serial interface to an ICOM using the "CI-V" interface. * * - * $Id: icom.h,v 1.21 2001-06-15 07:08:37 f4cfe Exp $ + * $Id: icom.h,v 1.22 2001-06-26 20:55:29 f4cfe Exp $ * * * This program is free software; you can redistribute it and/or @@ -99,6 +99,7 @@ int icom_mv_ctl(RIG *rig, vfo_t vfo, mv_op_t op); #else int icom_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); #endif +int icom_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int icom_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); diff --git a/icom/icom_defs.h b/icom/icom_defs.h index c71a7b388..8f4093363 100644 --- a/icom/icom_defs.h +++ b/icom/icom_defs.h @@ -6,7 +6,7 @@ * used by the ICOM "CI-V" interface. * * - * $Id: icom_defs.h,v 1.9 2001-06-10 22:27:08 f4cfe Exp $ + * $Id: icom_defs.h,v 1.10 2001-06-26 20:55:29 f4cfe Exp $ * * * This program is free software; you can redistribute it and/or @@ -131,8 +131,17 @@ /* * Scan control (C_CTL_SCAN) subcommands */ -#define S_STOP 0x00 /* Scan stop */ -#define S_START 0x01 /* Scan start */ +#define S_SCAN_STOP 0x00 /* Stop scan/window scan */ +#define S_SCAN_START 0x01 /* Programmed/Memory scan */ +#define S_SCAN_PROG 0x02 /* Programmed scan */ +#define S_SCAN_DELTA 0x03 /* Delta-f scan */ +#define S_SCAN_WRITE 0x04 /* auto memory-write scan */ +#define S_SCAN_FPROG 0x12 /* Fine programmed scan */ +#define S_SCAN_FDELTA 0x13 /* Fine delta-f scan */ +#define S_SCAN_MEM2 0x22 /* Memory scan */ +#define S_SCAN_SLCTN 0x23 /* Selected number memory scan */ +#define S_SCAN_SLCTM 0x24 /* Selected mode memory scan */ +#define S_SCAN_PRIO 0x42 /* Priority / window scan */ /* diff --git a/include/hamlib/rig.h b/include/hamlib/rig.h index b233fa299..48f5711e3 100644 --- a/include/hamlib/rig.h +++ b/include/hamlib/rig.h @@ -5,7 +5,7 @@ * will be used for obtaining rig capabilities. * * - * $Id: rig.h,v 1.41 2001-06-15 07:16:16 f4cfe Exp $ + * $Id: rig.h,v 1.42 2001-06-26 20:55:28 f4cfe Exp $ * * * This program is free software; you can redistribute it and/or @@ -356,6 +356,17 @@ typedef long vfo_op_t; #endif /* WANT_OLD_VFO_TO_BE_REMOVED */ +#define RIG_SCAN_NONE 0L +#define RIG_SCAN_STOP RIG_SCAN_NONE +#define RIG_SCAN_MEM (1L<<0) /* Scan all memory channels */ +#define RIG_SCAN_SLCT (1L<<1) /* Scan all selected memory channels */ +#define RIG_SCAN_PRIO (1L<<2) /* Priority watch (mem or call channel) */ +#define RIG_SCAN_PROG (1L<<3) /* Programmed(edge) scan */ +#define RIG_SCAN_DELTA (1L<<4) /* delta-f scan */ + +typedef long scan_t; + + /* * When optional speech synthesizer is installed * what about RIG_ANN_ENG and RIG_ANN_JAPAN? and RIG_ANN_CW? @@ -704,6 +715,7 @@ struct rig_caps { ann_t announces; vfo_op_t vfo_ops; + scan_t scan_ops; int targetable_vfo; int transceive; @@ -818,6 +830,7 @@ struct rig_caps { #else int (*vfo_op)(RIG *rig, vfo_t vfo, vfo_op_t op); #endif + int (*scan)(RIG *rig, vfo_t vfo, scan_t scan, int ch); int (*set_trn)(RIG *rig, vfo_t vfo, int trn); int (*get_trn)(RIG *rig, vfo_t vfo, int *trn); @@ -1109,6 +1122,8 @@ extern HAMLIB_EXPORT(int) rig_mv_ctl HAMLIB_PARAMS((RIG *rig, vfo_t vfo, mv_op_t extern HAMLIB_EXPORT(int) rig_vfo_op HAMLIB_PARAMS((RIG *rig, vfo_t vfo, vfo_op_t op)); extern HAMLIB_EXPORT(vfo_op_t) rig_has_vfo_op HAMLIB_PARAMS((RIG *rig, vfo_op_t op)); #endif +extern HAMLIB_EXPORT(int) rig_scan HAMLIB_PARAMS((RIG *rig, vfo_t vfo, scan_t scan, int ch)); +extern HAMLIB_EXPORT(scan_t) rig_has_scan HAMLIB_PARAMS((RIG *rig, scan_t scan)); extern HAMLIB_EXPORT(int) rig_restore_channel HAMLIB_PARAMS((RIG *rig, const channel_t *chan)); /* curr VFO */ extern HAMLIB_EXPORT(int) rig_save_channel HAMLIB_PARAMS((RIG *rig, channel_t *chan)); diff --git a/src/rig.c b/src/rig.c index 753f1f705..9a02800a8 100644 --- a/src/rig.c +++ b/src/rig.c @@ -2,7 +2,7 @@ Copyright (C) 2000,2001 Stephane Fillod and Frank Singleton This file is part of the hamlib package. - $Id: rig.c,v 1.36 2001-06-15 07:08:37 f4cfe Exp $ + $Id: rig.c,v 1.37 2001-06-26 20:55:28 f4cfe Exp $ Hamlib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -3183,11 +3183,11 @@ int rig_mv_ctl(RIG *rig, vfo_t vfo, mv_op_t op) * @op: The VFO op * * The rig_has_vfo_op() "macro" checks if a rig is capable of executing - * a VFO operation. Since the @op is a OR'ed bitmap argument, more than + * a VFO operation. Since the @op is an OR'ed bitmap argument, more than * one op can be checked at the same time. * * RETURN VALUE: The rig_has_vfo_op() "macro" returns a bitmap - * mask of supported op settings that can be retrieve, + * mask of supported op settings that can be retrieved, * 0 if none supported. * * EXAMPLE: if (rig_has_vfo_op(my_rig, RIG_OP_CPY)) disp_VFOcpy_btn(); @@ -3249,6 +3249,79 @@ int rig_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) } #endif /* WANT_OLD_VFO_TO_BE_REMOVED */ +/** + * rig_has_scan - check availability of scaning functions + * @rig: The rig handle + * @scan: The scan op + * + * The rig_has_scan() "macro" checks if a rig is capable of performing + * a scan operation. Since the @scan is an OR'ed bitmap argument, more than + * one op can be checked at the same time. + * + * RETURN VALUE: The rig_has_scan() "macro" returns a bitmap + * mask of supported scan settings that can be retrieved, + * 0 if none supported. + * + * EXAMPLE: if (rig_has_scan(my_rig, RIG_SCAN_PRIO)) disp_SCANprio_btn(); + * + * SEE ALSO: rig_scan() + */ +scan_t rig_has_scan(RIG *rig, scan_t scan) +{ + if (!rig || !rig->caps) + return 0; + + return (rig->caps->scan_ops & scan); +} + +/** + * rig_scan - perform Memory/VFO operations + * @rig: The rig handle + * @vfo: The target VFO + * @scan: The scanning operation to perform + * @ch: Optional channel argument used for the scan. + * + * The rig_scan() function performs scanning operation. + * See &scan_t for more information. + * + * RETURN VALUE: The rig_scan() function returns %RIG_OK + * if the operation has been sucessful, or a negative value + * if an error occured (in which case, cause is set appropriately). + * + * SEE ALSO: rig_has_scan() + */ + +int rig_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) +{ + const struct rig_caps *caps; + int retcode; + vfo_t curr_vfo; + + if (!rig || !rig->caps) + return -RIG_EINVAL; + + caps = rig->caps; + + if (caps->scan == NULL || + (scan!=RIG_SCAN_STOP && !rig_has_scan(rig, scan))) + return -RIG_ENAVAIL; + + if (caps->targetable_vfo || vfo == RIG_VFO_CURR || + vfo == rig->state.current_vfo) + return caps->scan(rig, vfo, scan, ch); + + if (!caps->set_vfo) + return -RIG_ENTARGET; + curr_vfo = rig->state.current_vfo; + retcode = caps->set_vfo(rig, vfo); + if (retcode != RIG_OK) + return retcode; + + retcode = caps->scan(rig, vfo, scan, ch); + caps->set_vfo(rig, curr_vfo); + return retcode; +} + /** * rig_send_dtmf - send DTMF digits * @rig: The rig handle diff --git a/tests/rigctl.c b/tests/rigctl.c index 9e7bba436..fcdace742 100644 --- a/tests/rigctl.c +++ b/tests/rigctl.c @@ -7,7 +7,7 @@ * TODO: be more generic and add command line option to run * in non-interactive mode * - * $Id: rigctl.c,v 1.15 2001-06-04 21:17:53 f4cfe Exp $ + * $Id: rigctl.c,v 1.16 2001-06-26 20:55:28 f4cfe Exp $ * * * This program is free software; you can redistribute it and/or @@ -89,6 +89,7 @@ declare_proto_rig(mv_ctl); #else declare_proto_rig(vfo_op); #endif +declare_proto_rig(scan); declare_proto_rig(set_channel); declare_proto_rig(get_channel); declare_proto_rig(set_trn); @@ -137,6 +138,7 @@ struct test_table test_list[] = { #else { 'G', "vfo_op", vfo_op, "Mem/VFO op" }, #endif + { 'g', "scan", scan, "Scan fct", "Channel" }, { 'H', "set_channel", set_channel /* huh! */ }, { 'h', "get_channel", get_channel, "Channel" }, { 'A', "set_trn", set_trn, "Transceive" }, @@ -711,6 +713,15 @@ declare_proto_rig(vfo_op) } #endif +declare_proto_rig(scan) +{ + scan_t op; + int ch; + + sscanf(arg1, "%d", (int*)&op); + sscanf(arg2, "%d", &ch); + return rig_scan(rig, RIG_VFO_CURR, op, ch); +} declare_proto_rig(set_channel) {