diff --git a/aor/ar7030.c b/aor/ar7030.c index 794a6b6c0..dba6e84a6 100644 --- a/aor/ar7030.c +++ b/aor/ar7030.c @@ -2,7 +2,7 @@ * Hamlib AOR backend - AR7030 description * Copyright (c) 2000-2004 by Stephane Fillod * - * $Id: ar7030.c,v 1.2 2004-08-26 20:46:03 fillods Exp $ + * $Id: ar7030.c,v 1.3 2004-12-08 21:13:25 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 @@ -20,12 +20,17 @@ * */ +// +// Version 2004.11.29 F.Melchert (DC9RP) +// + #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include +#include #include #include "aor.h" @@ -45,7 +50,7 @@ #define AR7030_FUNC_ALL (RIG_FUNC_NONE) -#define AR7030_LEVEL (RIG_LEVEL_NONE) +#define AR7030_LEVEL (RIG_LEVEL_AF|RIG_LEVEL_RF) #define AR7030_PARM (RIG_PARM_NONE) @@ -57,29 +62,367 @@ * Data was obtained from AR7030 pdf on http://www.aoruk.com */ -static int ar7030_set_freq(RIG *rig, vfo_t vfo, freq_t freq); -#ifdef AR7030Control_SOURCE -static int ar7030_open(RIG *rig); -static int ar7030_set_vfo(RIG *rig, vfo_t vfo); -static int ar7030_get_vfo(RIG *rig, vfo_t *vfo); -static int ar7030_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); -static int ar7030_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); -static int ar7030_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); -static int ar7030_set_powerstat(RIG *rig, powerstat_t status); -static char *ar7030_get_info(RIG *rig); -#endif -/* - * ar7030 rig capabilities. - * - * Parts from AR7030Control package, James A. Watson (jimbo@eureka.lk) - * and also from DReaM project - */ +/**************************************************************************** +* Misc Routines * +****************************************************************************/ + +static int rxr_writeByte(RIG *rig, unsigned char c) +{ + return write_block(&rig->state.rigport, &c, 1); +} + + +static int rxr_readByte(RIG *rig) +{ + unsigned char response[1]; + unsigned char buf[] = {0x71}; // Read command + int retval; + retval = write_block(&rig->state.rigport, buf, 1); + retval = read_block(&rig->state.rigport, response, 1); + return response[0]; +} + +/*! +Umwandlung von BCD nach char +*/ +int BCD_To_int(RIG *rig, int c) +{ + if (((c & 0x0F) < 0x0a) && ((c & 0xF0) < 0xa0)) // Test pseudo Tetrade + { + return (((c >> 4)*10)+(c & 0x0F)); + } + return (-1); +}// End of method BCD_To_char( + +/**************************************************************************** +* Routines to set receiver lock levels * +****************************************************************************/ + +/*! +Locks, or unlocks if called with argument 0, the receiver, disabling the +front panel controls or updates. The level of locking is determined by the +argument level which may be in the range 0 (no lock) to 3 (Remote operation +exclusively). Calling the method without arguments sets the lock level to +1. It is recommended to lock to this level during any multi byte read or +writes to prevent data contention between internal and remote access. +Calls with invalid arguments are ignored. +*/ +static void unlock(RIG *rig) +{ + rxr_writeByte(rig, 0x80); +} + +// Level 1 = 0x81 IR remote control disabled. +// Front panel buttons ignored. +// Front panel spin-wheels logged but not actioned. +// Display update (frequency & S-meter) continues. +static void setLock(RIG *rig, int level) +{ + if ((0 <= level) && (level <= 3)) { + rxr_writeByte(rig, 0x80+level); + } +} + +// Level 2 = 0x82 As level 1, but display update suspended. In revisions before 1.4 +// squelch operation is inhibited, which results in no audio output +// after a mode change. In revision 1.4 squelch operation continues +// and mode changing is as expected. +// Level 3 = 0x83 Remote operation exclusively. + + + +static void setMemPtr(RIG *rig, int page, int address) +{ + rxr_writeByte(rig, 0x50 + page); //Set Page + if (address <= 0xFF) { //*** <= 8 Bit Adresse *** + rxr_writeByte(rig, 0x30 + (address >> 4)); //Set H-Register 4 Bits + rxr_writeByte(rig, 0x40 + (address & 0x0F)); //Set Adress(12 Bits = (4 Bit H Register) + 8 Bit) + } else { //*** > 8 Bit Adresse *** + rxr_writeByte(rig, 0x30 + ((address >> 4) & 0x0F)) ;//Set H-Register 4 Bits + rxr_writeByte(rig, 0x40 + (address & 0x0F)); //Set Adress(12 Bits = (4 Bit H Register) + 8 Bit) + rxr_writeByte(rig, 0x10 + (address >> 8)); //Set Adress high(12 Bits=(4 Bit H Register)+8 Bit) + } +} + +/**************************************************************************** +* Routines * +****************************************************************************/ +// Routine 0 Reset Setup receiver as at switch-on. +// Routine 1 Set frequency Program local oscillator from frequ area and setup +// RF filters and oscillator range. +// Routine 2 Set mode Setup from mode byte in memory and display mode, +// select preferred filter and PBS, BFO values etc. +// Routine 3 Set passband Setup all IF parameters from filter, pbsval and bfoval bytes. +// Routine 4 Set all Set all receiver parameters from current memory values +static void Execute_Routine_4_1(RIG *rig, char mp , char ad , int numSteps) +{ + setLock(rig, 1); //Set Lock Level + setMemPtr(rig, mp , ad ); //page, address + // 0x30 = Set H-register x ---> H-register (4-bits) + // The high order 4-bits of each byte sent to the receiver is the operation code, + // the low order 4-bits is data (shown here as x) + rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps>>4))); + // 0x60 = Write data Hx + // ---> [Page, Address] Address register + 1 + // ---> Address register 0 + // ---> H-register, 0 + // ---> Mask register + rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps))); + + //Execute routine + //Set all Set all receiver parameters from current memory values + rxr_writeByte(rig, 0x24); + unlock(rig); //Set UnLock Level +} + +static void Execute_Routine_4_3(RIG *rig, char mp , char ad , int numSteps) +{ + setLock(rig, 1); //Set Lock Level + setMemPtr(rig, mp , ad ); //page, address + rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps>>20))); + rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps>>16))); + rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps>>12))); + rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps>>8))); + rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps>>4))); + rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps))); + + //Execute routine + //Set all Set all receiver parameters from current memory values + rxr_writeByte(rig, 0x24); + unlock(rig); //Set UnLock Level +} + +// Routine 5 Set audio Setup audio controller from memory register values. +// Routine 6 Set RF-IF Setup RF Gain, IF Gain and AGC speed. Also sets Notch Filter and +// Noise Blanker if these options are fitted. +static void Execute_Routine_6_1(RIG *rig, char mp , char ad , int numSteps) +{ + //setLock(rig, 1); //Set Lock Level + setMemPtr(rig, mp , ad ); //page, address + rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps>>4))); + rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps))); + rxr_writeByte(rig, 0x24); + //unlock(rig); //Set UnLock Level +} + + + + +// frequ Mem_Page=0 Address=1A +static int ar7030_set_freq(RIG *rig, vfo_t vfo, freq_t freq) +{ + unsigned int frequ_i = (int)(round(freq * .3766352228)); + Execute_Routine_4_3(rig, 0 , 0x1a , frequ_i); + return RIG_OK; +} +//frequ Mem_Page=0 Address=1A +static int ar7030_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) +{ + unsigned int frequ_i = 0; + setMemPtr(rig ,0 ,0x1a); + frequ_i = (int)(rxr_readByte(rig) << 16); + frequ_i = frequ_i + (int)(rxr_readByte(rig) << 8); + frequ_i = frequ_i + (int)(rxr_readByte(rig)); + *freq = ((float)(frequ_i) * 2.65508890157896); + return RIG_OK; +} + + +/*! +Current mode :- + RIG_MODE_NONE = 0, < None +1 = AM RIG_MODE_AM = (1<<0), < Amplitude Modulation +5 = CW RIG_MODE_CW = (1<<1), < CW +7 = USB RIG_MODE_USB = (1<<2), < Upper Side Band +6 = LSB RIG_MODE_LSB = (1<<3), < Lower Side Band +4 = Data RIG_MODE_RTTY = (1<<4), < Remote Teletype +3 = NFM RIG_MODE_FM = (1<<5), < "narrow" band FM + RIG_MODE_WFM = (1<<6), < broadcast wide FM + RIG_MODE_CWR = (1<<7), < CW reverse sideband + RIG_MODE_RTTYR = (1<<8), < RTTY reverse sideband +2 = Sync RIG_MODE_AMS = (1<<9), < Amplitude Modulation Synchronous + RIG_MODE_PKTLSB = (1<<10),< Packet/Digital LSB mode (dedicated port) + RIG_MODE_PKTUSB = (1<<11),< Packet/Digital USB mode (dedicated port) + RIG_MODE_PKTFM = (1<<12),< Packet/Digital FM mode (dedicated port) + RIG_MODE_ECSSUSB = (1<<13),< Exalted Carrier Single Sideband USB + RIG_MODE_ECSSLSB = (1<<14),< Exalted Carrier Single Sideband LSB + RIG_MODE_FAX = (1<<15) < Facsimile Mode +*/ +//m,M get_mode/set_mode FM, USB, LSB, CW, WFM, etc. passband is in Hz (pass 0 for default) +static int ar7030_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) +{ + // mode Mem_Page=0 Address=1D + switch(mode) + { + case RIG_MODE_AM : + Execute_Routine_4_1(rig, 0 , 0x1d , 1); //AM + break; + case RIG_MODE_AMS : + Execute_Routine_4_1(rig, 0 , 0x1d , 2); //Sync + break; + case RIG_MODE_FM : + Execute_Routine_4_1(rig, 0 , 0x1d , 3); //NFM + break; + case RIG_MODE_RTTY : + Execute_Routine_4_1(rig, 0 , 0x1d , 4); //Data + break; + case RIG_MODE_CW : + Execute_Routine_4_1(rig, 0 , 0x1d , 5); //CW + break; + case RIG_MODE_LSB : + Execute_Routine_4_1(rig, 0 , 0x1d , 6); //LSB + break; + case RIG_MODE_USB : + Execute_Routine_4_1(rig, 0 , 0x1d , 7); //USB + break; + default : + return -RIG_EINVAL; + } + + // filter Mem_Page=0 Address=34 + Execute_Routine_4_1(rig, 0, 0x34, width); + + return RIG_OK; +} + +static int ar7030_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) +{ + // mode Mem_Page=0 Address=1D * + setMemPtr(rig ,0 ,0x1d); + switch(rxr_readByte(rig)) + { + case 1: + *mode = RIG_MODE_AM; //AM + break; + case 2: + *mode = RIG_MODE_AMS; //Sync + break; + case 3: + *mode = RIG_MODE_FM; //NFM + break; + case 4: + *mode = RIG_MODE_RTTY; //Data + break; + case 5: + *mode = RIG_MODE_CW; //CW + break; + case 6: + *mode = RIG_MODE_LSB; //LSB + break; + case 7: + *mode = RIG_MODE_USB; //USB + break; + default : + return -RIG_EINVAL; + } + // fltbw Mem_Page=0 Address=38 + setMemPtr(rig ,0 ,0x38); + if ((*width = BCD_To_int(rig, rxr_readByte(rig))*100) < 0) + { + return -RIG_EINVAL; + } + + return RIG_OK; + +} + + +/*! + RIG_LEVEL_NONE = 0, < None + RIG_LEVEL_PREAMP = (1<<0), < Preamp, arg int (dB) + RIG_LEVEL_ATT = (1<<1), < Attenuator, arg int (dB) + RIG_LEVEL_VOX = (1<<2), < VOX delay, arg int (tenth of seconds) + RIG_LEVEL_AF = (1<<3), < Volume, arg float [0.0..1.0] + RIG_LEVEL_RF = (1<<4), < RF gain (not TX power), arg float [0.0..1.0] + RIG_LEVEL_SQL = (1<<5), < Squelch, arg float [0.0 .. 1.0] + RIG_LEVEL_IF = (1<<6), < IF, arg int (Hz) + RIG_LEVEL_APF = (1<<7), < APF, arg float [0.0 .. 1.0] + RIG_LEVEL_NR = (1<<8), < Noise Reduction, arg float [0.0 .. 1.0] + RIG_LEVEL_PBT_IN = (1<<9), < Twin PBT (inside), arg float [0.0 .. 1.0] + RIG_LEVEL_PBT_OUT = (1<<10),< Twin PBT (outside), arg float [0.0 .. 1.0] + RIG_LEVEL_CWPITCH = (1<<11),< CW pitch, arg int (Hz) + RIG_LEVEL_RFPOWER = (1<<12),< RF Power, arg float [0.0 .. 1.0] + RIG_LEVEL_MICGAIN = (1<<13),< MIC Gain, arg float [0.0 .. 1.0] + RIG_LEVEL_KEYSPD = (1<<14),< Key Speed, arg int (WPM) + RIG_LEVEL_NOTCHF = (1<<15),< Notch Freq., arg int (Hz) + RIG_LEVEL_COMP = (1<<16),< Compressor, arg float [0.0 .. 1.0] + RIG_LEVEL_AGC = (1<<17),< AGC, arg int (see enum agc_level_e) + RIG_LEVEL_BKINDL = (1<<18),< BKin Delay, arg int (tenth of dots) + RIG_LEVEL_BALANCE = (1<<19),< Balance (Dual Watch), arg float [0.0 .. 1.0] + RIG_LEVEL_METER = (1<<20),< Display meter, arg int (see enum meter_level_e) + + RIG_LEVEL_VOXGAIN = (1<<21),< VOX gain level, arg float [0.0 .. 1.0] + RIG_LEVEL_VOXDELAY = RIG_LEVEL_VOX, < VOX delay, arg int (tenth of seconds) + RIG_LEVEL_ANTIVOX = (1<<22),< anti-VOX level, arg float [0.0 .. 1.0] + RIG_LEVEL_LINEOUT = (1<<23),< Lineout Volume, arg float [0.0 .. 1.0] + + < These ones are not settable + RIG_LEVEL_RAWSTR = (1<<26),< Raw (A/D) value for signal strength, specific to each rig, arg int + RIG_LEVEL_SQLSTAT = (1<<27),< SQL status, arg int (open=1/closed=0). Deprecated, use get_dcd + instead + RIG_LEVEL_SWR = (1<<28),< SWR, arg float + RIG_LEVEL_ALC = (1<<29),< ALC, arg float + RIG_LEVEL_STRENGTH = (1<<30) < Effective (calibrated) signal strength relative to S9, arg int(dB) + RIG_LEVEL_BWC = (1<<31) < Bandwidth Control, arg int (Hz) +*/ +static int ar7030_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + float val_i = val.f; + switch(level) + { + case RIG_LEVEL_AF : + // af_vol Mem_Page=0 Address=1E + // Fehlerbehandlung + val_i = (val_i *100 / 2) + 15; + val_i = (val_i > 63) ? 63 : val_i; + val_i = (val_i < 15) ? 15 : val_i; + Execute_Routine_4_1(rig, 0 ,0x1e , val_i); + return RIG_OK; + case RIG_LEVEL_ATT : + return -RIG_ENIMPL; + case RIG_LEVEL_IF : + return -RIG_ENIMPL; + case RIG_LEVEL_RF : + // rfgain Mem_Page=0 Address=30 + Execute_Routine_6_1(rig, 0 ,0x30 , ((val_i * 10) - 1) * -1) ; + return RIG_OK; + default : + return -RIG_EINVAL; + } +} + +static int ar7030_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + switch(level) + { + case RIG_LEVEL_AF : + // af_vol Mem_Page=0 Address=1E + setMemPtr(rig ,0 ,0x1e); + val->f = ((float)(rxr_readByte(rig) - 15) * 2) / 100; + return RIG_OK; + case RIG_LEVEL_ATT : + return -RIG_ENIMPL; + case RIG_LEVEL_STRENGTH : + return -RIG_ENIMPL; + case RIG_LEVEL_IF : + return -RIG_ENIMPL; + case RIG_LEVEL_RF : + // rfgain Mem_Page=0 Address=30 + setMemPtr(rig ,0 ,0x30); + val->f = (float)((rxr_readByte(rig) * -1) + 1) / 10; + return RIG_OK; + default : + return -RIG_EINVAL; + } +} + + const struct rig_caps ar7030_caps = { .rig_model = RIG_MODEL_AR7030, .model_name = "AR7030", .mfg_name = "AOR", -.version = "0.2", +.version = "0.3", .copyright = "LGPL", .status = RIG_STATUS_ALPHA, .rig_type = RIG_TYPE_RECEIVER, @@ -93,7 +436,8 @@ const struct rig_caps ar7030_caps = { .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, /* TBC */ .write_delay = 0, -.post_write_delay = 0, +.post_write_delay = 0, //Device: /dev/ttyS0 +//.post_write_delay = 85, //Device: /dev/tts/USB0 < 85 sec timedout after 0 chars .timeout = 500, /* 0.5 second */ .retry = 0, .has_get_func = AR7030_FUNC_ALL, @@ -151,7 +495,7 @@ const struct rig_caps ar7030_caps = { {AR7030_MODES,kHz(200)}, {AR7030_MODES,kHz(250)}, {AR7030_MODES,kHz(500)}, -#if 0 +#if 0 {AR7030_MODES,0}, /* any tuning step */ #endif RIG_TS_END, @@ -166,563 +510,73 @@ const struct rig_caps ar7030_caps = { RIG_FLT_END, }, -.priv = NULL, -.rig_init = NULL, -.rig_cleanup = NULL, -#if 0 -.rig_open = ar7030_open, -#endif -.rig_close = NULL, + .priv = NULL, /* priv */ -.set_freq = ar7030_set_freq, -#if 0 -.get_freq = ar7030_get_freq, -.set_mode = ar7030_set_mode, -.get_mode = ar7030_get_mode, -.set_vfo = ar7030_set_vfo, -.get_vfo = ar7030_get_vfo, +// .rig_init = ar7030_init, +// .rig_cleanup = ar7030_cleanup, +// .rig_open = ar7030_open, +// .rig_close = ar7030_close, -.set_level = ar7030_set_level, -.get_level = ar7030_get_level, + .set_freq = ar7030_set_freq, + .get_freq = ar7030_get_freq, + .set_mode = ar7030_set_mode, + .get_mode = ar7030_get_mode, +// .set_vfo = ar7030_set_vfo, +// .get_vfo = ar7030_get_vfo, + +// .set_powerstat = ar7030_set_powerstat, +// .get_powerstat = ar7030_get_powerstat, + .set_level = ar7030_set_level, + .get_level = ar7030_get_level, +// .set_func = ar7030_set_func, +// .get_func = ar7030_get_func, +// .set_parm = ar7030_set_parm, +// .get_parm = ar7030_get_parm, -//.get_parm = ar7030_get_parm, +// .get_info = ar7030_get_info, -.set_powerstat = ar7030_set_powerstat, -.get_info = ar7030_get_info, -#endif +// .set_ptt = ar7030_set_ptt, +// .get_ptt = ar7030_get_ptt, +// .get_dcd = ar7030_get_dcd, +// .set_rptr_shift = ar7030_set_rptr_shift, +// .get_rptr_shift = ar7030_get_rptr_shift, +// .set_rptr_offs = ar7030_set_rptr_offs, +// .get_rptr_offs = ar7030_get_rptr_offs, +// .set_ctcss_tone = ar7030_set_ctcss_tone, +// .get_ctcss_tone = ar7030_get_ctcss_tone, +// .set_dcs_code = ar7030_set_dcs_code, +// .get_dcs_code = ar7030_get_dcs_code, +// .set_ctcss_sql = ar7030_set_ctcss_sql, +// .get_ctcss_sql = ar7030_get_ctcss_sql, +// .set_dcs_sql = ar7030_set_dcs_sql, +// .get_dcs_sql = ar7030_get_dcs_sql, +// .set_split_freq = ar7030_set_split_freq, +// .get_split_freq = ar7030_get_split_freq, +// .set_split_mode = ar7030_set_split_mode, +// .get_split_mode = ar7030_get_split_mode, +// .set_split_vfo = ar7030_set_split_vfo, +// .get_split_vfo = ar7030_get_split_vfo, +// .set_rit = ar7030_set_rit, +// .get_rit = ar7030_get_rit, +// .set_xit = ar7030_set_xit, +// .get_xit = ar7030_get_xit, +// .set_ts = ar7030_set_ts, +// .get_ts = ar7030_get_ts, +// .set_ant = ar7030_set_ant, +// .get_ant = ar7030_get_ant, +// .set_bank = ar7030_set_bank, +// .set_mem = ar7030_set_mem, +// .get_mem = ar7030_get_mem, +// .vfo_op = ar7030_vfo_op, +// .scan = ar7030_scan, +// .send_dtmf = ar7030_send_dtmf, +// .recv_dtmf = ar7030_recv_dtmf, +// .send_morse = ar7030_send_morse, +// .set_channel = ar7030_set_channel, +// .get_channel = ar7030_get_channel, +// .set_trn = ar7030_set_trn, +// .get_trn = ar7030_get_trn, }; -/* - * Function definitions below - */ - - - -static int rxr_writeByte(RIG *rig, unsigned char c) -{ - return write_block(&rig->state.rigport, &c, 1); -} - -static int rxr_readByte(RIG *rig, unsigned char *c) -{ - unsigned char buf[] = {0x71}; // Read command - int retval; - - retval = write_block(&rig->state.rigport, buf, 1); - if (retval != RIG_OK) - return retval; - - retval = read_block(&rig->state.rigport, c, 1); - - return retval; -} - -int ar7030_set_freq(RIG *rig, vfo_t vfo, freq_t freq) -{ - unsigned numSteps = (unsigned)((double)freq * .376635223 + 0.5); - - if (vfo != RIG_VFO_CURR) - return -RIG_EINVAL; - - rxr_writeByte(rig, 0x50); /* Select working mem (page 0) */ - rxr_writeByte(rig, 0x31); /* Frequency address = 01AH */ - rxr_writeByte(rig, 0x4A); - - - /* Exact multiplicand is (2^24) / 44545 */ - rxr_writeByte(rig, 0x30 + numSteps/1048576); - numSteps %= 1048576; - rxr_writeByte(rig, 0x60 + numSteps/65536); - numSteps %= 65536; - rxr_writeByte(rig, 0x30 + numSteps/4096); - numSteps %= 4096; - rxr_writeByte(rig, 0x60 + numSteps/256); - numSteps %= 256; - rxr_writeByte(rig, 0x30 + numSteps/16); - numSteps %= 16; - rxr_writeByte(rig, 0x60 + numSteps); - - rxr_writeByte(rig, 0x21); - rxr_writeByte(rig, 0x2C); - - return RIG_OK; -} - -/* - * The following code is a WIP, and not complete yet - */ -#ifdef AR7030Control_SOURCE -/*! -Sets all of the receivers parameters from current memory values. This routine -must be called after setFreq(), setMode() etc. -*/ -static int tune(RIG *rig) -{ - return rxr_writeByte(rig, 0x24); -} - - -int ar7030_open(RIG *rig) -{ - _numFilters=0; // number of filters fitted - _enhanced=1; // 0 = type A, 1 = type 'B' - - getIdent(_idString); - if ( (_idString[7] == 'A') ) { - _enhanced = 0; - } else { - _enhanced = 1; - } - unsigned char tmpchr; - for (int i = 1; i < 7 ; i++) { - setMemPtr(rig, 1, (0x85 + (0x04 * (i-1))) ); - if (retval != RIG_OK) return retval; - - retval = rxr_readByte(rig, &tmpchr); - if (retval != RIG_OK) return retval; - - _filterBandWidth[i] = (tmpchr == 0xFF) ? 0.0 : ((float)charToBCD(tmpchr))/10.0; - if (_filterBandWidth[i] > 0.0) { - _numFilters++; - } - } - - _firmwareVersion = (float)(strtod(_idString+5,0))/10.0; - -} - - - -/*! -Writes the sets ident to a char buffer specified by the pointer id. -No checks are made on the size of the buffer which must be at least 15 chars. -*/ -char *ar7030_get_info(RIG *rig) -{ - static char ident[15]; - int i, retval; - - retval = rxr_writeByte(rig, 0x5F); - if (retval != RIG_OK) return retval; - - retval = rxr_writeByte(rig, 0x40); - if (retval != RIG_OK) return retval; - - for (i=0; i<8 ; i++) { - retval = rxr_readByte(rig, ident+i); - if (retval != RIG_OK) return retval; - } - ident[i]='\0'; - - return ident; -} - - - - - -/**************************************************************************** -* Frequency Routines. * -****************************************************************************/ - -/*! -Sets the frequency (in kHz) to the value specified by freq. The frequency -change does not become effective until the next tune(). Caution, there is -no checking yet i.e. it is up to the programmer to make sure that only valid -frequencies are entered. -*/ -int ar7030_set_freq(RIG *rig, vfo_t vfo, freq_t freq) -{ - int numSteps = (int)(freq * 376.635223 + 0.5); - - /* - * VFO: setMemPtr(RIG, 0,0x1a); - */ - if (vfo != RIG_VFO_CURR) - return -RIG_EINVAL; - -// TODO some checks here for validity of input values -// - rxr_writeByte(rig, 0x30+(int)(numSteps/1048576)); - numSteps %= 1048576; - rxr_writeByte(rig, 0x60+(int)(numSteps/65536)); - numSteps %= 65536; - rxr_writeByte(rig, 0x30+(int)(numSteps/4096)); - numSteps %= 4096; - rxr_writeByte(rig, 0x60+(int)(numSteps/256)); - numSteps %= 256; - rxr_writeByte(rig, 0x30+(int)(numSteps/16)); - numSteps %= 16; - rxr_writeByte(rig, 0x60+(int)(numSteps % 16)); - - tune(rig); - - return RIG_OK; -} - - - -static int readFreq(RIG *rig, freq_t *freq) -{ - int i, frVal = 0; - unsigned char readVal = 0; - - for (i=0 ; i<3 ; i++) { - retval = rxr_readByte(rig, &readVal); - if (retval != RIG_OK) - return retval; - frVal = (frVal*256)+readVal; - } - } - *freq = (freq_t)((double)frVal/376635.223); /* Hz */ - - return RIG_OK; -} - -/*! -Returns the current frequency in kHz. -*/ -int ar7030_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) -{ - float f; - - setMemPtr(0,0x1a); - *freq = (freq_t)readFreq(); - - return RIG_OK; -} - - - - -/**************************************************************************** -* Mode select and interrogation Routines. * -* 1=AM, 2=SYNC, 3=NFM, 7=USB, 4=DATA, 5=CW, 6=LSB * -****************************************************************************/ -int ar7030_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) -{ - unsigned char mdbuf[BUFSZ],ackbuf[BUFSZ]; - int mdbuf_len, ack_len, aormode, retval; - - switch (mode) { - case RIG_MODE_FM: aormode = MD_FM; break; - case RIG_MODE_AM: aormode = MD_AM; break; - case RIG_MODE_CW: aormode = MD_CW; break; - case RIG_MODE_USB: aormode = MD_USB; break; - case RIG_MODE_LSB: aormode = MD_LSB; break; - default: - rig_debug(RIG_DEBUG_ERR,"%s: unsupported mode %d\n", - __FUNCTION__,mode); - return -RIG_EINVAL; - } - - mdbuf_len = sprintf(mdbuf, "MD%c" EOM, aormode); - retval = aor_transaction (rig, mdbuf, mdbuf_len, ackbuf, &ack_len); - - tune(rig); - - return retval; -} - -#define MD_AM 1 -#define MD_SYNC 2 -#define MD_FM 3 -#define MD_USB 7 -#define MD_DATA 4 -#define MD_CW 5 -#define MD_LSB 6 - -/*! -Returns the current mode, represented by an integer. 1=AM, 2=SYNC, 3=NFM, -7=USB, 4=DATA, 5=CW, 6=LSB. -*/ -int ar7030_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) -{ - int m, retval; - - retval = setMemPtr(rig, 0,0x1d); // Select working mem (page 0). - - if (retval != RIG_OK) - return retval; - - m = rxr_readByte(rig); - - *width = RIG_PASSBAND_NORMAL; - switch (m) { - case MD_AM: *mode = RIG_MODE_AM; break; - case MD_SYNC: *mode = RIG_MODE_AMS; break; - case MD_CW: *mode = RIG_MODE_CW; break; - case MD_FM: *mode = RIG_MODE_FM; break; - case MD_USB: *mode = RIG_MODE_USB; break; - case MD_LSB: *mode = RIG_MODE_LSB; break; - default: - rig_debug(RIG_DEBUG_ERR,"%s: unsupported mode %d\n", - __FUNCTION__, m); - return -RIG_EPROTO; - } -int AR7030::getFilter() const { - int c = 0; - setMemPtr(0,0x34); - c=(int)rxr.readByte(); - return c; -} // End of method getFilter - - if (*width == RIG_PASSBAND_NORMAL) - *width = rig_passband_normal(rig, *mode); - - return RIG_OK; -} - - - -/*! -Returns the bandwidth, in kHz, of the filter specified by f. If the value -of f is greater than the number of filters, a value of 0 is returned. -*/ -static float ar7030_getFilterBandWidth(int f) const { - if ( (f>0) && (f<=6) ) { - return _filterBandWidth[f]; - } else { - return 0.0; - } -} // End of method getFilterBandWidth() - - -/*! -Returns the number of filters fitted to the set. -*/ -int AR7030::getNumFilters() const { - return _numFilters; -} - - - -/*! -Sets the current mode to that represented by the integer m, defined as -follows; 1=AM, 2=SYNC, 3=NFM, 7=USB, 4=DATA, 5=CW, 6=LSB. The mode -change does not come into effect until the next tune() command. -*/ -int ar7030_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) -{ - int retval, m; - - retval = setMemPtr(rig, 0,0x1d); - if (retval != RIG_OK) - return retval; - - switch (mode) { - case RIG_MODE_FM: m = MD_FM; break; - case RIG_MODE_AM: m = MD_AM; break; - case RIG_MODE_AMS: m = MD_SYNC; break; - case RIG_MODE_CW: m = MD_CW; break; - case RIG_MODE_USB: m = MD_USB; break; - case RIG_MODE_LSB: m = MD_LSB; break; - default: - rig_debug(RIG_DEBUG_ERR,"%s: unsupported mode %d\n", - __FUNCTION__,mode); - return -RIG_EINVAL; - } - -/*! -Sets the filter. Valid arguments depend on the set being -controlled. Standard sets have four filters and an option for two more. -Calls with invalid arguments are ignored. -*/ -void AR7030::setFilter(int f) const { - if ((f <= _numFilters) && (f > 0)) { //check valid filter number - setMemPtr(0,0x34); - rxr.writeByte(0x60+f); - } -} // End of method setFilter() - - retval = rxr_writeByte(rig, 0x60 + m); - - return retval; -} - - -#if 0 -/**************************************************************************** -* Memory Routines * -* Memory data is handled in structure type ar7030Memory :- * -* int number, int sql, float freq, int filter, int mode * -* float pbs, char textID[15], bool scanLockout * -* * -****************************************************************************/ - -/* -A few private routines to set the memory pointer to locations containing -frequency etc. No checks on the input value are made in these routines. -*/ - -void AR7030::setPtrFreqMem(int n) const { - if ( n <= 99 ) { - setMemPtr(2, (0x00 + (4 * n))); - } else { - setMemPtr(3, (0x00 + (4 * (n - 100))) ); - } -} - -void AR7030::setPtrSQLMem(int n) const { -/* -Firmware version 1.7 has a bug that puts the SQL/BFO -data in a memory 100 lower than it should be. -*/ - int mapBugOffset = (_firmwareVersion == (float)1.7) ? 100 : 0; - if ( n <= 99 ) { // SQL/BFO - setMemPtr(1, (0x9C + n) ); - } else if ( (100 <= n) && (n <= (175+mapBugOffset) ) ) { - setMemPtr(3, ( 0x500 + (16 * (n-mapBugOffset) ) ) ); - } else { - setMemPtr(4,(16 * (n-(176+mapBugOffset) ) ) ); - } -} // End of method setPtrSQLMem() - - -void AR7030::setPtrPBSMem(int n) const { - int mapBugOffset = (_firmwareVersion == (float)1.7) ? 100 : 0; - if ( n <= 99 ) { // PBS - setMemPtr(2,(0x190 + n)); - } else if ( (100 <= n) && (n <= (175 +mapBugOffset) ) ) { - setMemPtr(3, (0x501 + (16 * (n-mapBugOffset) ) ) ); - } else { - setMemPtr(4,(0x01+(16 * (n-(176+mapBugOffset)) ) ) ); - } -} // End of method setPtrPBSMem() - - -void AR7030::setPtrIdentMem(int n) const { - if ( n <= 175 ) { - setMemPtr(3,(0x502 + (16 * n) ) ); - } else { - setMemPtr(4,(0x02 + (16 * (n-176)))); - } -} // End of method setPtrIdentMem() - - -/*! -Writes the contents of a memory location specified by num to a variable of -the type ar7070MemoryData, mem. The definition of the type -ar7030MemoryData is pert of the file ar7030.h. Checks are made as to the -validity of the argument num and invalid calls will result in the mem member -freq containing a value of 0.0. -*/ -void AR7030::getMem(int num,ar7030MemoryData &mem) const { - - if ( (num < 0) || (!_enhanced && (num>99)) ) { // check for valid number - return; - } - unsigned char chr; - - mem.number = num; - - mem.freq = readMemFreq(num); // Frequency - - chr = rxr.readByte(); // Mode/Filter/scan byte follows frequency - mem.mode = chr & 0x0F; - mem.filter = (chr >> 4) & 0x07; - mem.scanLockout = (chr >> 7); - - setPtrSQLMem(num); //BFO for CW and data modes - if ((mem.mode==4) || (mem.mode==5)) { - mem.bfo = rxr.readByte()*0.03319; - } else { // SQL for all others - mem.sql=(int)( ( (float)rxr.readByte()*99.0 )/150.0); - } - - setPtrPBSMem(num); // PBS - mem.pbs = 0.03319 * (signed char)rxr.readByte(); // convert to kHz - - if ( _enhanced ) { // Text - setPtrIdentMem(num); - for (int i=0; i<14 ; i++) { - mem.textID[i]=(char)rxr.readByte(); - } - mem.textID[14]='\0'; - } -} // End of method getMem() - - -/*! -Sets the contents of a memory location to that defined in the variable of type -ar7070MemoryData, mem. The definition of the type ar7030MemoryData is pert of the -file ar7030.h. This function has not been fully tested yet. -*/ -void AR7030::setMem(ar7030MemoryData &mem) const { - - if ( (mem.number < 0) || (!_enhanced && (mem.number>99)) ) { - return; - } - unsigned char tmpchr = 0; // general purpose temporary variable - - setPtrFreqMem(mem.number); - writeFreq(mem.freq); - -// TODO fast find memory - - tmpchr = (mem.mode & 0x0F) | (mem.filter << 4) | (mem.scanLockout << 7); - rxr.writeByte(0x30 + (tmpchr>>4)); - rxr.writeByte(0x60 + (tmpchr & 0x0F)); - - setPtrSQLMem(mem.number); // BFO for CW and Data modes - if ((mem.mode==4) || (mem.mode==5)) { - tmpchr = (unsigned char)(mem.bfo/0.03319); - rxr.writeByte(0x30 + (tmpchr >> 4)); - rxr.writeByte(0x60 + (tmpchr & 0x0F)); - } else { // SQL for all other modes - tmpchr = (unsigned char)( (mem.sql*150.0)/99.0); - rxr.writeByte(0x30 + (tmpchr >> 4)); - rxr.writeByte(0x60 + (tmpchr & 0x0F)); - } - - setPtrPBSMem(mem.number); //PBS - (signed)tmpchr = mem.pbs/0.03319; - rxr.writeByte(0x30 + (tmpchr >> 4)); - rxr.writeByte(0x60 + (tmpchr & 0x0F)); - - if ( _enhanced ) { // Ident - setPtrIdentMem(mem.number); - for (int i=0; i<14 ; i++) { - tmpchr = mem.textID[i]; - rxr.writeByte(0x30 + (tmpchr >> 4)); - rxr.writeByte(0x60 + (tmpchr & 0x0F)); - } - } -} // End of method setMem() - - -/*! -Returns the frequency in the memory specified by num. -*/ -float AR7030::getMemFreq(int num) const { - if ( (num<0) || (!_enhanced && (num >99)) || (num>399) ) { - return 0.0; - } - return readMemFreq(num); -} // End of method getMemFreq() - - -float AR7030::readMemFreq(int num) const { - setPtrFreqMem(num); - return readFreq(); -} // End of method readFreq() - - - - -/*! -Turns the receiver on from standby mode. -*/ -int ar7030_set_powerstat(RIG *rig, powerstat_t status) -{ - if (status != RIG_POWER_ON) - return -RIG_EINVAL; - - return rxr_writeByte(rig, 0xA0); -} - -#endif - -#endif /* AR7030Control_SOURCE */