kopia lustrzana https://github.com/Hamlib/Hamlib
				
				
				
			
		
			
				
	
	
		
			665 wiersze
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			665 wiersze
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
| /*
 | |
|  *  Hamlib Kenwood backend - TM-V7 description
 | |
|  *  Copyright (c) 2004-2010 by Stephane Fillod
 | |
|  *
 | |
|  *
 | |
|  *   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 program 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.
 | |
|  *
 | |
|  *   You should have received a copy of the GNU Library General Public
 | |
|  *   License along with this library; if not, write to the Free Software
 | |
|  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #include "config.h"
 | |
| #endif
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <stdio.h>
 | |
| #include <string.h>  /* String function definitions */
 | |
| #include <unistd.h>  /* UNIX standard function definitions */
 | |
| 
 | |
| #include <hamlib/rig.h>
 | |
| #include "kenwood.h"
 | |
| #include "th.h"
 | |
| #include "misc.h"
 | |
| #include "num_stdio.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 TMV7_FUNC_ALL (\
 | |
|                        RIG_FUNC_TBURST \
 | |
|                        )
 | |
| 
 | |
| #define TMV7_LEVEL_ALL (\
 | |
| 			RIG_LEVEL_RAWSTR| \
 | |
|                         RIG_LEVEL_SQL| \
 | |
|                         RIG_LEVEL_AF| \
 | |
|                         RIG_LEVEL_RFPOWER\
 | |
| 			)
 | |
| 
 | |
| #define TMV7_CHANNEL_CAPS \
 | |
| .freq=1,\
 | |
| .tx_freq=1,\
 | |
| .mode=1,\
 | |
| .tuning_step=1,\
 | |
| .rptr_shift=1,\
 | |
| .ctcss_tone=1,\
 | |
| .ctcss_sql=1,\
 | |
| .channel_desc=1
 | |
| 
 | |
| #ifndef RIG_TONEMAX
 | |
| #define RIG_TONEMAX     38
 | |
| #endif
 | |
| 
 | |
| #define RIG_VFO_A_OP (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TO_VFO)
 | |
| 
 | |
| #define ACKBUF_LEN 128
 | |
| 
 | |
| static rmode_t tmv7_mode_table[KENWOOD_MODE_TABLE_MAX] = {
 | |
|     [0] = RIG_MODE_FM,
 | |
|     [1] = RIG_MODE_AM,
 | |
| };
 | |
| 
 | |
| static struct kenwood_priv_caps  tmv7_priv_caps  = {
 | |
|     .cmdtrm =  EOM_TH,   /* Command termination character */
 | |
|     .mode_table = tmv7_mode_table,
 | |
| };
 | |
| 
 | |
| 
 | |
| /* tmv7 procs */
 | |
| static int tmv7_decode_event (RIG *rig);
 | |
| static int tmv7_set_vfo (RIG *rig, vfo_t vfo);
 | |
| static int tmv7_get_mode (RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width);
 | |
| static int tmv7_get_powerstat (RIG *rig, powerstat_t *status);
 | |
| static int tmv7_get_channel(RIG *rig, channel_t *chan);
 | |
| static int tmv7_set_channel(RIG *rig, const channel_t *chan);
 | |
| 
 | |
| /*
 | |
|  * tm-v7 rig capabilities.
 | |
|  */
 | |
| const struct rig_caps tmv7_caps = {
 | |
| .rig_model =  RIG_MODEL_TMV7,
 | |
| .model_name = "TM-V7",
 | |
| .mfg_name =  "Kenwood",
 | |
| .version =  TH_VER,
 | |
| .copyright =  "LGPL",
 | |
| .status =  RIG_STATUS_BETA,
 | |
| .rig_type =  RIG_TYPE_MOBILE,
 | |
| .ptt_type =  RIG_PTT_RIG,
 | |
| .dcd_type =  RIG_DCD_RIG,
 | |
| .port_type =  RIG_PORT_SERIAL,
 | |
| .serial_rate_min =  9600,
 | |
| .serial_rate_max =  9600,
 | |
| .serial_data_bits =  8,
 | |
| .serial_stop_bits =  1,
 | |
| .serial_parity =  RIG_PARITY_NONE,
 | |
| .serial_handshake =  RIG_HANDSHAKE_NONE,
 | |
| .write_delay =  1,
 | |
| .post_write_delay =  0,
 | |
| .timeout =  500,
 | |
| .retry =  3,
 | |
| 
 | |
| .has_set_func =  TMV7_FUNC_ALL,
 | |
| .has_get_level =  TMV7_LEVEL_ALL,
 | |
| .has_set_level =  RIG_LEVEL_SET(TMV7_LEVEL_ALL),
 | |
| .level_gran = {
 | |
| 	[LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 7 } },
 | |
| 	[LVL_SQL] = { .min = { .i = 0 }, .max = { .i = 32 } },
 | |
| 	[LVL_AF] = { .min = { .i = 0 }, .max = { .i = 32 } },
 | |
| 	[LVL_RFPOWER] = { .min = { .i = 0 }, .max = { .i = 2 } },
 | |
| },
 | |
| .parm_gran =  {},
 | |
| .ctcss_list =  kenwood38_ctcss_list,
 | |
| .dcs_list =  NULL,
 | |
| .preamp =   { RIG_DBLST_END, },
 | |
| .attenuator =   { RIG_DBLST_END, },
 | |
| .max_rit =  Hz(0),
 | |
| .max_xit =  Hz(0),
 | |
| .max_ifshift =  Hz(0),
 | |
| .vfo_ops =  RIG_VFO_A_OP,
 | |
| .targetable_vfo =  RIG_TARGETABLE_NONE,
 | |
| .transceive =  RIG_TRN_RIG,
 | |
| .bank_qty =   0,
 | |
| .chan_desc_sz =  6,
 | |
| 
 | |
| 
 | |
| .chan_list =  { 
 | |
| 		{  1, 90 , RIG_MTYPE_MEM , {TMV7_CHANNEL_CAPS}},  /* normal MEM VHF */
 | |
| 		{ 101, 190, RIG_MTYPE_MEM , {TMV7_CHANNEL_CAPS}},  /* normal MEM UHF */
 | |
| 		{  201,206, RIG_MTYPE_EDGE , {TMV7_CHANNEL_CAPS}}, /* L MEM */
 | |
| 		{  211,216, RIG_MTYPE_EDGE , {TMV7_CHANNEL_CAPS}}, /* U MEM */
 | |
| 		{  221,222, RIG_MTYPE_CALL , {TMV7_CHANNEL_CAPS}}, /* Call V/U */
 | |
| 		RIG_CHAN_END,
 | |
| 		   },
 | |
| 
 | |
| .rx_range_list1 =  {
 | |
|         {MHz(118),MHz(174),RIG_MODE_AM | RIG_MODE_FM,-1,-1,RIG_VFO_A},
 | |
|         {MHz(300),MHz(470),RIG_MODE_FM,-1,-1,RIG_VFO_B},
 | |
|         RIG_FRNG_END,
 | |
|   }, /* rx range */
 | |
| 
 | |
| .tx_range_list1 =  {
 | |
|         {MHz(118),MHz(174), RIG_MODE_FM,W(5),W(50),RIG_VFO_A},
 | |
|         {MHz(300),MHz(470),RIG_MODE_FM,W(5),W(35),RIG_VFO_B},
 | |
|         RIG_FRNG_END,
 | |
|   }, /* tx range */
 | |
| 
 | |
| .rx_range_list2 =  {
 | |
|         {MHz(118),MHz(174),RIG_MODE_AM | RIG_MODE_FM,-1,-1,RIG_VFO_A},
 | |
|         {MHz(300),MHz(470),RIG_MODE_FM,-1,-1,RIG_VFO_B},
 | |
|         RIG_FRNG_END,
 | |
|   }, /* rx range */
 | |
| 
 | |
| .tx_range_list2 =  {
 | |
|         {MHz(118),MHz(174), RIG_MODE_FM,W(5),W(50),RIG_VFO_A},
 | |
|         {MHz(300),MHz(470),RIG_MODE_FM,W(5),W(35),RIG_VFO_B},
 | |
|         RIG_FRNG_END,
 | |
|   }, /* tx range */
 | |
| 
 | |
| .tuning_steps =  {
 | |
| 	 {RIG_MODE_FM,kHz(5)},
 | |
| 	 {RIG_MODE_FM,kHz(6.25)},
 | |
| 	 {RIG_MODE_FM,kHz(10)},
 | |
| 	 {RIG_MODE_FM,kHz(12.5)},
 | |
| 	 {RIG_MODE_FM,kHz(15)},
 | |
| 	 {RIG_MODE_FM,kHz(25)},
 | |
| 	 {RIG_MODE_FM,kHz(50)},
 | |
| 	 RIG_TS_END,
 | |
| 	},
 | |
|         /* mode/filter list, remember: order matters! */
 | |
| .filters =  {
 | |
| 	RIG_FLT_END,
 | |
| 	},
 | |
| 
 | |
| .str_cal ={ 4, { {0, -60 }, {1, -30,}, {5,0}, {7,20}}}, /* rought guess */
 | |
| 
 | |
| .priv =  (void *)&tmv7_priv_caps,
 | |
| .rig_init = kenwood_init,
 | |
| .rig_cleanup = kenwood_cleanup,
 | |
| .rig_open = kenwood_open,
 | |
| .rig_close =  NULL,
 | |
| 
 | |
| .set_freq =  th_set_freq,
 | |
| .get_freq =  th_get_freq,
 | |
| .get_mode =  tmv7_get_mode,
 | |
| .set_vfo =  tmv7_set_vfo,
 | |
| .get_vfo =  th_get_vfo,
 | |
| .set_mem =  th_set_mem,
 | |
| .get_mem =  th_get_mem,
 | |
| .set_channel =  tmv7_set_channel,
 | |
| .get_channel =  tmv7_get_channel,
 | |
| .set_trn =  th_set_trn,
 | |
| .get_trn =  th_get_trn,
 | |
| 
 | |
| .set_func =  th_set_func,
 | |
| .get_func =  th_get_func,
 | |
| .get_level = th_get_level,
 | |
| .set_level = th_set_level,
 | |
| .get_info =  th_get_info,
 | |
| .get_powerstat =  tmv7_get_powerstat,
 | |
| .vfo_op = th_vfo_op,
 | |
| .set_ptt = th_set_ptt,
 | |
| .get_dcd=th_get_dcd,
 | |
| .decode_event =  tmv7_decode_event,
 | |
| };
 | |
| 
 | |
| 
 | |
| /* --------------------------------------------------------------------- */
 | |
| int tmv7_decode_event (RIG *rig)
 | |
| {
 | |
|     char asyncbuf[ACKBUF_LEN];
 | |
|     int retval;
 | |
|     size_t asyncbuf_len = ACKBUF_LEN;
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
 | |
| 
 | |
|     retval = kenwood_transaction(rig, NULL, 0, asyncbuf, &asyncbuf_len);
 | |
|     if (retval != RIG_OK)
 | |
|         return retval;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: Decoding message\n", __func__);
 | |
| 
 | |
|     if (asyncbuf[0] == 'B' && asyncbuf[1] == 'U' && asyncbuf[2] == 'F') {
 | |
| 
 | |
|         freq_t freq, offset;
 | |
|         int step, shift, rev, tone, ctcss, tonefq, ctcssfq;
 | |
| 
 | |
|         retval = num_sscanf(asyncbuf, "BUF 0,%"SCNfreq",%d,%d,%d,%d,%d,,%d,,%d,%"SCNfreq,
 | |
|                                   &freq, &step, &shift, &rev, &tone,
 | |
|                                   &ctcss, &tonefq, &ctcssfq, &offset);
 | |
|         if (retval != 11) {
 | |
|             rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BUF message '%s'\n", __func__, asyncbuf);
 | |
|             return -RIG_ERJCTED;
 | |
|         }
 | |
| 
 | |
|         rig_debug(RIG_DEBUG_TRACE, "%s: Buffer (freq %"PRIfreq" Hz, mode %d)\n", __func__, freq);
 | |
| 
 | |
|         /* Callback execution */
 | |
|         if (rig->callbacks.vfo_event) {
 | |
|             rig->callbacks.vfo_event(rig, RIG_VFO_A, rig->callbacks.vfo_arg);
 | |
|         }
 | |
|         if (rig->callbacks.freq_event) {
 | |
|             rig->callbacks.freq_event(rig, RIG_VFO_A, freq, rig->callbacks.freq_arg);
 | |
|         }
 | |
| 	/* 
 | |
|         if (rig->callbacks.mode_event) {
 | |
|             rig->callbacks.mode_event(rig, RIG_VFO_A, mode, RIG_PASSBAND_NORMAL,
 | |
| 							rig->callbacks.mode_arg);
 | |
|         }
 | |
| 	*/
 | |
| 
 | |
|     /* --------------------------------------------------------------------- */
 | |
|     } else if (asyncbuf[0] == 'S' && asyncbuf[1] == 'M') {
 | |
| 
 | |
|         int lev;
 | |
|         retval = sscanf(asyncbuf, "SM 0,%d", &lev);
 | |
|         if (retval != 2) {
 | |
|             rig_debug(RIG_DEBUG_ERR, "%s: Unexpected SM message '%s'\n", __func__, asyncbuf);
 | |
|             return -RIG_ERJCTED;
 | |
|         }
 | |
| 
 | |
|         rig_debug(RIG_DEBUG_TRACE, "%s: Signal strength event - signal = %.3f\n", __func__, (float)(lev / 5.0));
 | |
| 
 | |
|         /* Callback execution */
 | |
| #if STILLHAVETOADDCALLBACK
 | |
|         if (rig->callbacks.strength_event)
 | |
|             rig->callbacks.strength_event(rig, RIG_VFO_0,(float)(lev / 5.0),
 | |
| 							rig->callbacks.strength_arg);
 | |
| #endif
 | |
| 
 | |
|     /* --------------------------------------------------------------------- */
 | |
|     } else if (asyncbuf[0] == 'B' && asyncbuf[1] == 'Y') {
 | |
| 
 | |
|         int busy;
 | |
| 
 | |
|         retval = sscanf(asyncbuf, "BY 0,%d", &busy);
 | |
|         if (retval != 2) {
 | |
|             rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BY message '%s'\n", __func__, asyncbuf);
 | |
|             return -RIG_ERJCTED;
 | |
|         }
 | |
|         rig_debug(RIG_DEBUG_TRACE, "%s: Busy event - status = '%s'\n",
 | |
| 				__func__, (busy == 0) ? "OFF" : "ON" );
 | |
|         return -RIG_ENIMPL;
 | |
|         /* This event does not have a callback. */
 | |
| 
 | |
|     /* --------------------------------------------------------------------- */
 | |
|     } else if (asyncbuf[0] == 'V' && asyncbuf[1] == 'M' && asyncbuf[2] == 'C') {
 | |
| 
 | |
|         vfo_t bandmode;
 | |
| 
 | |
|         retval = sscanf(asyncbuf, "VMC 0,%d", &bandmode);
 | |
|         if (retval != 1) {
 | |
|             rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VMC message '%s'\n", __func__, asyncbuf);
 | |
|             return -RIG_ERJCTED;
 | |
|         }
 | |
| 
 | |
|         switch (bandmode) {
 | |
|             case 0:     bandmode = RIG_VFO_VFO;  break;
 | |
|             case 2:     bandmode = RIG_VFO_MEM;  break;
 | |
|           /*  case 3:     bandmode = RIG_VFO_CALL; break; */
 | |
|             default:    bandmode = RIG_VFO_CURR; break; 
 | |
|         }
 | |
|         rig_debug(RIG_DEBUG_TRACE, "%s: Mode of Band event -  %d\n", __func__,  bandmode);
 | |
| 
 | |
|         /* TODO: This event does not have a callback! */
 | |
|         return -RIG_ENIMPL;
 | |
|     /* --------------------------------------------------------------------- */
 | |
|     } else {
 | |
| 
 | |
|         rig_debug(RIG_DEBUG_ERR, "%s: Unsupported transceive cmd '%s'\n", __func__, asyncbuf);
 | |
|         return -RIG_ENIMPL;
 | |
|     }
 | |
| 
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* --------------------------------------------------------------------- */
 | |
| int tmv7_set_vfo (RIG *rig, vfo_t vfo)
 | |
| {
 | |
|     char vfobuf[16], ackbuf[ACKBUF_LEN];
 | |
|     int retval;
 | |
|     size_t ack_len;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: called %d\n", __func__,vfo);
 | |
| 
 | |
| 	switch (vfo) {
 | |
|         case RIG_VFO_A:
 | |
|         case RIG_VFO_VFO:
 | |
|             sprintf(vfobuf, "VMC 0,0");
 | |
|             break;
 | |
|         case RIG_VFO_B:
 | |
|             sprintf(vfobuf, "VMC 1,0");
 | |
|             break;
 | |
|         case RIG_VFO_MEM:
 | |
|             sprintf(vfobuf, "BC");
 | |
|     	    ack_len=ACKBUF_LEN;
 | |
| 	    retval = kenwood_transaction(rig, vfobuf, strlen(vfobuf), ackbuf, &ack_len);
 | |
| 	    if (retval != RIG_OK) return retval;
 | |
|             sprintf(vfobuf, "VMC %c,2",ackbuf[3]);
 | |
|             break;
 | |
|         default:
 | |
|             rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %d\n", __func__, vfo);
 | |
|             return -RIG_EVFO;
 | |
| 	}
 | |
| 
 | |
|     ack_len=0;
 | |
|     retval = kenwood_transaction(rig, vfobuf, strlen(vfobuf), ackbuf, &ack_len);
 | |
| 	if (retval != RIG_OK) {
 | |
|             rig_debug(RIG_DEBUG_ERR, "%s: bad return \n", __func__);
 | |
|         return retval;
 | |
|     }
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: next %d\n", __func__,vfo);
 | |
| 	switch (vfo) {
 | |
|         case RIG_VFO_A:
 | |
|         case RIG_VFO_VFO:
 | |
|             sprintf(vfobuf, "BC 0,0");
 | |
|             break;
 | |
|         case RIG_VFO_B:
 | |
|             sprintf(vfobuf, "BC 1,1");
 | |
|             break;
 | |
|         case RIG_VFO_MEM:
 | |
|             return RIG_OK;
 | |
| 	default:
 | |
| 		return RIG_OK;
 | |
| 	}
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: next2\n", __func__);
 | |
|     ack_len=0;
 | |
|     retval = kenwood_transaction(rig, vfobuf, strlen(vfobuf), ackbuf, &ack_len);
 | |
| 	if (retval != RIG_OK)
 | |
|         return retval;
 | |
| 
 | |
|     return RIG_OK;
 | |
| }
 | |
| 
 | |
| /* --------------------------------------------------------------------- */
 | |
| int tmv7_get_mode (RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
 | |
| {
 | |
|     char ackbuf[ACKBUF_LEN];
 | |
|     int retval;
 | |
|     size_t ack_len=ACKBUF_LEN;
 | |
|     int step;
 | |
|     freq_t freq;
 | |
| 
 | |
|     rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
 | |
| 
 | |
| 	switch (vfo) {
 | |
|       case RIG_VFO_CURR: break;
 | |
|       case RIG_VFO_A: break;
 | |
| 	  default:
 | |
|         rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %d\n", __func__, vfo);
 | |
| 		return -RIG_EVFO;
 | |
| 	}
 | |
| 
 | |
| 	/* try to guess from frequency */
 | |
|     retval = kenwood_transaction(rig, "FQ", 3, ackbuf, &ack_len);
 | |
|         if (retval != RIG_OK)
 | |
|         return retval;
 | |
| 
 | |
|     num_sscanf(ackbuf,"FQ %"SCNfreq",%d",&freq,&step);
 | |
| 
 | |
|     if(freq <MHz(137) )  {
 | |
| 		*mode=RIG_MODE_AM;
 | |
| 		*width=kHz(9);
 | |
| 	} else {
 | |
| 		*mode=RIG_MODE_FM;
 | |
| 		*width=kHz(12);
 | |
| 	}
 | |
| 
 | |
| 	return RIG_OK;
 | |
| }
 | |
| 
 | |
| int tmv7_get_powerstat (RIG *rig, powerstat_t *status)
 | |
| {
 | |
| /* dummy func to make sgcontrol happy */
 | |
| 
 | |
| 	*status=RIG_POWER_ON;
 | |
| 	return RIG_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* --------------------------------------------------------------------- */
 | |
| int tmv7_get_channel(RIG *rig, channel_t *chan)
 | |
| {
 | |
|     char membuf[64],ackbuf[ACKBUF_LEN];
 | |
|     int retval;
 | |
|     size_t ack_len;
 | |
|     freq_t freq;
 | |
|     char req[16],scf[128];
 | |
|     int step, shift, rev, tone, ctcss, tonefq, ctcssfq;
 | |
| 
 | |
|     if(chan->channel_num<100)
 | |
|     	sprintf(req,"MR 0,0,%03d",chan->channel_num);
 | |
|     else
 | |
|     if(chan->channel_num<200)
 | |
|     	sprintf(req,"MR 1,0,%03d",chan->channel_num-100);
 | |
|     else
 | |
|     if(chan->channel_num<204) {
 | |
|     	sprintf(req,"MR 0,0,L%01d",chan->channel_num-200);
 | |
|         sprintf(chan->channel_desc,"L%01d/V",chan->channel_num-200);
 | |
|     } else
 | |
|     if(chan->channel_num<211) {
 | |
|     	sprintf(req,"MR 1,0,L%01d",chan->channel_num-203);
 | |
|         sprintf(chan->channel_desc,"L%01d/U",chan->channel_num-203);
 | |
|     } else
 | |
|     if(chan->channel_num<214) {
 | |
|    	sprintf(req,"MR 0,0,U%01d",chan->channel_num-210);
 | |
|         sprintf(chan->channel_desc,"U%01d/V",chan->channel_num-210);
 | |
|     } else
 | |
|     if(chan->channel_num<220) {
 | |
|    	sprintf(req,"MR 1,0,U%01d",chan->channel_num-213);
 | |
|         sprintf(chan->channel_desc,"U%01d/U",chan->channel_num-213);
 | |
|     } else
 | |
|     if(chan->channel_num<223) {
 | |
|         if(chan->channel_num==221) {
 | |
|     		 sprintf(req,"CR 0,0");
 | |
| 		 sprintf(chan->channel_desc,"Call V");
 | |
| 	}
 | |
|         if(chan->channel_num==222) {
 | |
|     		 sprintf(req,"CR 1,0");
 | |
| 		 sprintf(chan->channel_desc,"Call U");
 | |
| 	}
 | |
|     } else
 | |
| 	return -RIG_EINVAL;
 | |
| 
 | |
|     sprintf(membuf,"%s",req);
 | |
|     ack_len=ACKBUF_LEN;
 | |
|     retval = kenwood_transaction(rig, membuf, strlen(membuf), ackbuf, &ack_len);
 | |
|         if (retval != RIG_OK)
 | |
|         	return retval;
 | |
| 
 | |
|     strcpy(scf,req);
 | |
|     strcat(scf,",%"SCNfreq",%d,%d,%d,%d,0,%d,%d,000,%d,,0");
 | |
|     retval = num_sscanf(ackbuf, scf,
 | |
|                     &freq, &step, &shift, &rev, &tone,
 | |
|                     &ctcss, &tonefq, &ctcssfq);
 | |
| 
 | |
|     chan->freq=freq;
 | |
|     chan->vfo=RIG_VFO_MEM;
 | |
|     chan->tuning_step=rig->state.tuning_steps[step].ts;
 | |
|     if(freq <MHz(138) )  {
 | |
| 		chan->mode=RIG_MODE_AM;
 | |
|     } else {
 | |
| 		chan->mode=RIG_MODE_FM;
 | |
|     }
 | |
|     switch(shift) {
 | |
| 	case 0 :
 | |
| 		chan->rptr_shift=RIG_RPT_SHIFT_NONE;
 | |
| 		break;
 | |
| 	case 1 :
 | |
| 		chan->rptr_shift=RIG_RPT_SHIFT_PLUS;
 | |
| 		break;
 | |
| 	case 2 :
 | |
| 		chan->rptr_shift=RIG_RPT_SHIFT_MINUS;
 | |
| 		break;
 | |
|     }
 | |
| 
 | |
|     if(tone)
 | |
| 	 chan->ctcss_tone=rig->caps->ctcss_list[tonefq==1?0:tonefq-2];
 | |
|     else
 | |
| 	 chan->ctcss_tone=0;
 | |
|     if(ctcss)
 | |
| 	 chan->ctcss_sql=rig->caps->ctcss_list[ctcssfq==1?0:ctcssfq-2];
 | |
|     else
 | |
| 	 chan->ctcss_sql=0;
 | |
| 
 | |
|     chan->tx_freq=RIG_FREQ_NONE;
 | |
|     if(chan->channel_num<223 && shift==0) {
 | |
| 	req[5]='1';
 | |
|         sprintf(membuf,"%s",req);
 | |
|         ack_len=ACKBUF_LEN;
 | |
|     	retval = kenwood_transaction(rig, membuf, strlen(membuf), ackbuf, &ack_len);
 | |
|         if (retval == RIG_OK) {
 | |
|     		strcpy(scf,req);
 | |
|     		strcat(scf,",%"SCNfreq",%d");
 | |
|     		retval = num_sscanf(ackbuf, scf, &freq, &step);
 | |
| 		chan->tx_freq=freq;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     if(chan->channel_num<200) {
 | |
| 	    if(chan->channel_num<100)
 | |
| 	    	sprintf(membuf,"MNA 0,%03d",chan->channel_num);
 | |
| 	    else
 | |
| 	    	sprintf(membuf,"MNA 1,%03d",chan->channel_num-100);
 | |
|         ack_len=ACKBUF_LEN;
 | |
|     	retval = kenwood_transaction(rig, membuf, strlen(membuf), ackbuf, &ack_len);
 | |
|         if (retval != RIG_OK)
 | |
|         	return retval;
 | |
|         memcpy(chan->channel_desc,&ackbuf[10],7);
 | |
|     }
 | |
| 
 | |
|     return RIG_OK;
 | |
| }
 | |
| /* --------------------------------------------------------------------- */
 | |
| int tmv7_set_channel(RIG *rig, const channel_t *chan)
 | |
| {
 | |
|     char membuf[ACKBUF_LEN],ackbuf[ACKBUF_LEN];
 | |
|     int retval;
 | |
|     size_t ack_len;
 | |
|     char req[64];
 | |
|     long freq;   
 | |
|     int chn, step, shift, tone, ctcss, tonefq, ctcssfq;
 | |
| 
 | |
|     chn=chan->channel_num;
 | |
|     freq=(long)chan->freq;
 | |
| 
 | |
|     for(step=0; rig->state.tuning_steps[step].ts!=0;step++)
 | |
| 	if(chan->tuning_step==rig->state.tuning_steps[step].ts) break;
 | |
| 
 | |
|     switch(chan->rptr_shift) {
 | |
| 	case RIG_RPT_SHIFT_NONE :
 | |
| 		shift=0;
 | |
| 		break;
 | |
| 	case  RIG_RPT_SHIFT_PLUS:
 | |
| 		shift=1;
 | |
| 		break;
 | |
| 	case RIG_RPT_SHIFT_MINUS:
 | |
| 		shift=2;
 | |
| 		break;
 | |
|         default:
 | |
|             rig_debug(RIG_DEBUG_ERR, "%s: not supported shift\n", __func__);
 | |
|             return -RIG_EINVAL;
 | |
|     }
 | |
|     
 | |
|     if(chan->ctcss_tone==0) {
 | |
| 	 tone=0;tonefq=9;
 | |
|     } else {
 | |
| 	 tone=1;
 | |
|     	for (tonefq = 0; rig->caps->ctcss_list[tonefq] != 0 && tonefq < RIG_TONEMAX; tonefq++) {
 | |
| 		if (rig->caps->ctcss_list[tonefq] == chan->ctcss_tone)
 | |
| 			break;
 | |
| 	}
 | |
| 	tonefq=tonefq==0?1:tonefq+2;
 | |
|     }
 | |
|     if(chan->ctcss_sql==0) {
 | |
| 	ctcss=0;ctcssfq=9;
 | |
|     } else {
 | |
| 	 ctcss=1;
 | |
|     	for (ctcssfq = 0; rig->caps->ctcss_list[ctcssfq] != 0 && ctcssfq < RIG_TONEMAX; ctcssfq++) {
 | |
| 		if (rig->caps->ctcss_list[ctcssfq] == chan->ctcss_sql)
 | |
| 			break;
 | |
| 	}
 | |
| 	 ctcssfq=ctcssfq==0?1:ctcssfq+2;
 | |
|     }
 | |
| 
 | |
|     if(chan->channel_num<100)
 | |
|     	sprintf(req,"MW 0,0,%03d",chan->channel_num);
 | |
|     else
 | |
|     if(chan->channel_num<200)
 | |
|     	sprintf(req,"MW 1,0,%03d",chan->channel_num-100);
 | |
|     else
 | |
|     if(chan->channel_num<204) {
 | |
|     	sprintf(req,"MW 0,0,L%01d",chan->channel_num-200);
 | |
|     } else
 | |
|     if(chan->channel_num<211) {
 | |
|     	sprintf(req,"MW 1,0,L%01d",chan->channel_num-203);
 | |
|     } else
 | |
|     if(chan->channel_num<214) {
 | |
|    	sprintf(req,"MW 0,0,U%01d",chan->channel_num-210);
 | |
|     } else
 | |
|     if(chan->channel_num<220) {
 | |
|    	sprintf(req,"MW 1,0,U%01d",chan->channel_num-213);
 | |
|     } else
 | |
|     if(chan->channel_num<223) {
 | |
|         if(chan->channel_num==221) {
 | |
|     		 sprintf(req,"CW 0,0");
 | |
| 	}
 | |
|         if(chan->channel_num==222) {
 | |
|     		 sprintf(req,"CW 1,0");
 | |
| 	}
 | |
|     } else
 | |
| 	return -RIG_EINVAL;
 | |
| 
 | |
|     if(chan->channel_num<221)
 | |
|     	sprintf(membuf, "%s,%011ld,%01d,%01d,0,%01d,%01d,0,%02d,000,%02d,0,0",
 | |
|                     req,(long)freq, step, shift, tone,
 | |
|                     ctcss, tonefq, ctcssfq);
 | |
|     else
 | |
|     	sprintf(membuf, "%s,%011ld,%01d,%01d,0,%01d,%01d,0,%02d,000,%02d,",
 | |
|                     req, (long)freq, step, shift, tone,
 | |
|                     ctcss, tonefq, ctcssfq);
 | |
| 
 | |
|     ack_len=0;
 | |
|     retval = kenwood_transaction(rig, membuf, strlen(membuf), ackbuf, &ack_len);
 | |
|         if (retval != RIG_OK)
 | |
|         	return retval;
 | |
| 
 | |
|     if(chan->tx_freq!=RIG_FREQ_NONE) {
 | |
|     	req[5]='1';
 | |
|     	sprintf(membuf, "%s,%011"PRIll",%01d", req, (int64_t)chan->tx_freq, step);
 | |
|         ack_len=0;
 | |
|     	retval = kenwood_transaction(rig, membuf, strlen(membuf), ackbuf, &ack_len);
 | |
|         if (retval != RIG_OK)
 | |
|         	return retval;
 | |
|     }
 | |
| 
 | |
|     if(chan->channel_num<200) {
 | |
| 	    if(chan->channel_num<100)
 | |
| 	    	sprintf(membuf,"MNA 0,%03d,%s",chan->channel_num,chan->channel_desc);
 | |
| 	    else
 | |
| 	    	sprintf(membuf,"MNA 1,%03d,%s",chan->channel_num-100,chan->channel_desc);
 | |
|     	ack_len=0;
 | |
|     	retval = kenwood_transaction(rig, membuf, strlen(membuf), ackbuf, &ack_len);
 | |
|         if (retval != RIG_OK)
 | |
|         	return retval;
 | |
|     }
 | |
| 
 | |
|     return RIG_OK;
 | |
| }
 |